【题目描述】
猪王国的文明源远流长,博大精深。
iPigiPigiPig 在大肥猪学校图书馆中查阅资料,得知远古时期猪文文字总个数为 nnn。当然,一种语言如果字数很多,字典也相应会很大。当时的猪王国国王考虑到如果修一本字典,规模有可能远远超过康熙字典,花费的猪力、物力将难以估量。故考虑再三没有进行这一项劳猪伤财之举。当然,猪王国的文字后来随着历史变迁逐渐进行了简化,去掉了一些不常用的字。
iPigiPigiPig 打算研究古时某个朝代的猪文文字。根据相关文献记载,那个朝代流传的猪文文字恰好为远古时期的 1/k1/k1/k,其中 kkk 是 nnn 的一个正约数(可以是 111 或 nnn)。不过具体是哪 1/k1/k1/k,以及 kkk 是多少,由于历史过于久远,已经无从考证了。
iPigiPigiPig 觉得只要符合文献,每一种 k∣nk|nk∣n 都是有可能的。他打算考虑到所有可能的 kkk。显然当 kkk 等于某个定值时,该朝的猪文文字个数为 n/kn/kn/k。然而从 nnn 个文字中保留下 n/kn/kn/k 个的情况也是相当多的。iPigiPigiPig 预计,如果所有可能的 kkk 的所有情况数加起来为 ppp 的话,那么他研究古代文字的代价将会是 gpg^pgp。
现在他想知道猪王国研究古代文字的代价是多少。由于 iPigiPigiPig 觉得这个数字可能是天文数字,所以你只需要告诉他答案除以 999911659999911659999911659 的余数就可以了。
【输入格式】
一行两个正整数 n,gn,gn,g。
【输出格式】
输出一行一个整数表示答案。
【输入输出样例】
输入
4 2
输出
2048
【数据规模与约定】
- 对于 10%10\%10% 的数据,1≤n≤501\le n \le 501≤n≤50;
- 对于 20%20\%20% 的数据,1≤n≤10001\le n \le 10001≤n≤1000;
- 对于 40%40\%40% 的数据,1≤n≤1051\le n \le 10^51≤n≤105;
- 对于 100%100\%100% 的数据,1≤n,g≤1091\le n,g \le 10^91≤n,g≤109。
【算法分析】
本题实际上就是求 q∑d∣nCndmod 999911659q^{\sum_{d|n}C_n^d}mod\ 999911659q∑d∣nCndmod 999911659 。ddd 是 nnn 的约数。
根据欧拉定理:若 a,na,na,n 互质,对于任意的整数 bbb ,有 ab≡ab mod φ(n)(mode n)a^b\equiv a^{b\ mod\ \varphi (n)}(mode\ n)ab≡ab mod φ(n)(mode n),φ(n)\varphi (n)φ(n) 是欧拉函数。
若 q=999911659q=999911659q=999911659,则上式结果为 000 ,否则,因为 999911659999911659999911659 是质数,与任何数互质,因此:
q∑d∣nCnd≡q∑d∣nCnd mod 999911658(mod 999911659)q^{\sum_{d|n}C_n^d}\equiv q^{\sum_{d|n}C_n^d\ mod \ 999911658}(mod\ 999911659)q∑d∣nCnd≡q∑d∣nCnd mod 999911658(mod 999911659)。
现在就转换为求解 qqq 的次方:∑d∣nCnd mod 999911658\sum_{d|n}C_n^d\ mod \ 999911658∑d∣nCnd mod 999911658 。
因为模数较大,若直接使用 LucasLucasLucas 定理会超时。尝试将模数缩小。
将 999911658999991165899999116589 质因数分解,可得 999911658=2×3×4679×35617999911658=2\times 3\times 4679\times 35617999911658=2×3×4679×35617,可以使用 LucasLucasLucas 定理计算组合数 ∑d∣nCnd\sum_{d|n}C_n^d∑d∣nCnd 模 2,3,4679,356172,3,4679,356172,3,4679,35617 分别为 a1,a2,a3,a4a_1,a_2,a_3,a_4a1,a2,a3,a4,在计算过程中,对于质数 ppp ,可以预处理出1!∼p!1!\sim p!1!∼p! 模 ppp ,以及阶乘模 ppp 的逆元,可以快速求解出组合数模 ppp 的值。
那么 ∑d∣nCnd mode 999911658\sum_{d|n}C_n^d\ mode \ 999911658∑d∣nCnd mode 999911658 的解 xxx 满足:
{x≡a1(mod 2)x≡a2(mod 3)x≡a2(mod 4679)x≡an(mod 35617)\left\{\begin{matrix} x\equiv a_1(mod\ 2) \\ x\equiv a_2(mod\ 3) \\ x\equiv a_2(mod\ 4679)\\ x\equiv a_n(mod\ 35617) \\ \end{matrix}\right.⎩⎪⎪⎨⎪⎪⎧x≡a1(mod 2)x≡a2(mod 3)x≡a2(mod 4679)x≡an(mod 35617)
得到 xxx 的最小正整数解,最后的答案就是 qxq^xqx ,可以使用快速幂求解。
本题是数论的综合应用,欧拉定理+LucasLucasLucas 定理+乘法逆元+中国剩余定理+快速幂 。
【参考程序】
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=100010;
ll divv[N],cnt;
ll KSM(ll x,ll k,ll P) //快速幂
{
ll ans=1;
while(k)
{
if(k&1) ans=(ans*x)%P;
k>>=1;
x=(x*x)%P;
}
return ans%P;
}
//组合数C(n,m)=n!/(m!*(n-m)!)=n!/(n-m)!取模乘以m!模P的逆元
//P是质数,可以使用费马小定理
ll C(ll n,ll m,ll P)
{
ll a=1,b=1;
for(int i=n-m+1;i<=n;i++) a=(a*i)%P;
for(int i=2;i<=m;i++) b=(b*i)%P;
return (a*KSM(b,P-2,P))%P; //费马小定理求逆元
}
ll Lucas(ll x,ll y,ll P)
{
if(!y) return 1;
if(x<y) return 0;
if(x<P&&y<P) return C(x,y,P);
return (Lucas(x%P,y%P,P)*Lucas(x/P,y/P,P))%P;
}
int main()
{
ll n,g;
scanf("%lld%lld",&n,&g);
if(g%999911659==0) {cout<<0;return 0;}
for(int i=1;i*i<=n;i++) //找约数
{
if(i*i==n) divv[++cnt]=n/i;
else if(n%i==0) divv[++cnt]=i,divv[++cnt]=n/i;
}
ll a1=0;
for(int i=1;i<=cnt;i++)
a1=(a1+Lucas(n,divv[i],2))%2;
ll a2=0;
for(int i=1;i<=cnt;i++)
a2=(a2+Lucas(n,divv[i],3))%3;
ll a3=0;
for(int i=1;i<=cnt;i++)
a3=(a3+Lucas(n,divv[i],4679))%4679;
ll a4=0;
for(int i=1;i<=cnt;i++)
a4=(a4+Lucas(n,divv[i],35617))%35617;
ll P=999911658;
//中国剩余定理,由于2,3,679,35617是质数,可以直接使用费马小定理求解
ll ans=(a1*P/2*KSM(P/2,2-2,2))%P+(a2*P/3*KSM(P/3,3-2,3))%P+(a3*P/4679*KSM(P/4679,4679-2,4679))%P+(a4*P/35617*KSM(P/35617,35617-2,35617))%P;
ans=((ans%P)+P)%P; //取最小正整数
cout<<KSM(g,ans,P+1)<<endl;
return 0;
}