题意:
求这个东西:
G∑k|nkCknmod 999911659
题解:
这题就是把几个模板弄在一起。
首先欧拉定理:
G∑k|nkCknmod ϕ(999911659)mod 999911659
=G∑k|nkCknmod 999911658mod 999911659
然后将999911658拆成2*3*4679*35617四个质数,然后lucas求组合数,再中国剩余定理合并就可以了。
code:
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<cstring>
#define LL long long
using namespace std;
LL p[5]={2,3,4679,35617};
const LL mod=999911659,MOD=999911658;
LL n,g,f[5][36000],inv[5][36000],b=0;
LL pow(LL a,LL b,LL mod)
{
LL ans=1;
while(b)
{
if(b&1) ans=ans*a%mod;
a=a*a%mod;b>>=1;
}
return ans;
}
LL C(LL n,LL m,LL op)
{
if(m>n) return 0;
return f[op][n]*inv[op][n-m]%p[op]*inv[op][m]%p[op];
}
void pre()
{
for(LL k=0;k<4;k++)
{
f[k][0]=f[k][1]=inv[k][1]=inv[k][0]=1;
for(LL i=2;i<=p[k];i++) f[k][i]=f[k][i-1]*i%p[k],inv[k][i]=inv[k][p[k]%i]*(p[k]-p[k]/i)%p[k];
for(LL i=2;i<=p[k];i++) inv[k][i]=inv[k][i]*inv[k][i-1]%p[k];
}
}
LL lucas(LL n,LL m,LL op)
{
if (m>n) return 0;
LL ans=1;
for (;m;n/=p[op],m/=p[op])
ans=ans*C(n%p[op],m%p[op],op)%p[op];
return ans;
}
LL INV(LL a,LL p) {return pow(a,p-2,p);}
void solve(LL m)
{
LL ans=0;
for(LL k=0;k<4;k++)
{
LL tmp=lucas(n,m,k);
ans=(ans+tmp*(MOD/p[k])%MOD*INV(MOD/p[k],p[k])%MOD)%MOD;
}
b=(b+ans)%MOD;
}
int main()
{
scanf("%lld %lld",&n,&g);
pre();
if(g==mod) {printf("0");return 0;}
for(LL i=1;i*i<=n;i++)
if(n%i==0)
{
solve(i);
if(i*i!=n) solve(n/i);
}
printf("%lld",pow(g,b,mod));
}