一句话题意:G 的 sigma d|n C(n d) 次幂 mod 999911659
(我好辣鸡呀还是不会mathjax)
分析:
1.利用欧拉定理简化模运算 ,将上方幂设为x,则x=原式mod 999911658.
2.发现幂的前半部分太大无法直接算,又因为999911658 可分解为 2 3 4679 35617 四个质数
3.利用中国剩余定理可分别计算 x=a1(mod m1=2) ...最后利用它统计出x
4.快速幂将答案计算
#include<bits/stdc++.h> #define int long long #define rep(i,x,y) for(register int i=x;i<=y;i++) #define dec(i,x,y) for(register int i=x;i>=y;i--) using namespace std; const int mod=999911659; int n,g,m[6]={0,2,3,4679,35617},a[6]; int fac[50050][5]; inline int qpow(int a,int n,int p){ int s=1;while(n){if(n&1) s=s*a%p;a=a*a%p;n>>=1;}return s;} inline void init(){ fac[0][1]=fac[0][2]=fac[0][3]=fac[0][4]=1; rep(i,1,50000)rep(j,1,4) fac[i][j]=fac[i-1][j]*i%m[j];} inline int C(int a,int b,int c){ if(a<b) return 0; return fac[a][c]*qpow(fac[b][c],m[c]-2,m[c])%m[c]*qpow(fac[a-b][c],m[c]-2,m[c])%m[c]; } inline int Lucas(int a,int b,int c){ if(!b) return 1; return C(a%m[c],b%m[c],c)*Lucas(a/m[c],b/m[c],c)%m[c];} inline void work(int i){ rep(j,1,4) a[j]=(a[j]+Lucas(n,i,j))%m[j];} inline int CRT(){ int x=0,M=mod-1; rep(i,1,4){ int Mi=M/m[i]; x=(x+a[i]*Mi*qpow(Mi,m[i]-2,m[i])%M)%M;}return x;} #undef int int main(){ #define int long long scanf("%lld%lld",&n,&g); init(); if(g%mod==0) {printf("0");return 0;} rep(i,1,sqrt(n)) if(n%i==0){ work(i); if(i*i!=n) work(n/i);} printf("%lld\n",qpow(g,CRT(),mod));return 0; }