题目:
题解:
题目就是让求
G∑k|NC(N,k)%p
G
∑
k
|
N
C
(
N
,
k
)
%
p
根据欧拉定理:
aφ(n)≡1(%n)
a
φ
(
n
)
≡
1
(
%
n
)
,我们知道指数只要到了φ(n),得出来的都是1了,那么柿子可以画成
然后因为模数是质数,φ(p)=p-1=999911658=2*3*4679*35617,这显然不是个质数了,模数不是质数怎么办啊?
可以用Lucas定理+中国剩余定理合并。诶这东西好像是扩展Lucas,但是要是真写的话会T,因为扩Lucas中的模数只是互质而不是质数。但这道题很好办啊都是质数
还有一个小细节就是当gcd(g,mod)!=1的时候不能使用欧拉定理,这个时候直接输出0就好咯
代码:
#include <cstdio>
using namespace std;
#define LL long long
const int mod=999911659;
const int phi=mod-1;
LL mul[5][35620],p[5],c[5],ans;
LL ksm(LL a,LL k,LL mod)
{
LL ans=1;
for (;k;k>>=1,a=a*a%mod)
if (k&1) ans=ans*a%mod;
return ans;
}
LL gcd(LL a,LL b){if (!b) return a;else return gcd(b,a%b);}
void exgcd(int a,int b,LL &x,LL &y){if (!b) x=1,y=0;else exgcd(b,a%b,y,x),y-=a/b*x;}
LL C(LL n,LL m,int i)
{
if (m>n) return 0;
return mul[i][n]*ksm(mul[i][m]*mul[i][n-m]%p[i],p[i]-2,p[i])%p[i];
}
LL Lucas(LL n,LL m,int i)
{
if (m>n) return 0;
LL ans=1;
for (;m;n/=p[i],m/=p[i]) ans=(ans*C(n%p[i],m%p[i],i))%p[i];
return ans;
}
void init()
{
p[1]=2; p[2]=3; p[3]=4679; p[4]=35617;
for (int i=1;i<=4;i++)
{
mul[i][0]=1;
for (int j=1;j<=35617;j++) mul[i][j]=j%p[i]*mul[i][j-1]%p[i];
}
}
int main()
{
init();LL n,g;
scanf("%lld%lld",&n,&g);
if (gcd(g,mod)!=1) {printf("0");return 0;}
for (int i=1;i*i<=n;i++)
if (n%i==0)
{
for (int j=1;j<=4;j++) c[j]=(c[j]+Lucas(n,i,j))%p[j];
if (n/i!=i) for (int j=1;j<=4;j++) c[j]=(c[j]+Lucas(n,n/i,j))%p[j];
}
for (int i=1;i<=4;i++)
{
LL a=phi/p[i],b=p[i],x,y;
exgcd(a,b,x,y);
x=(x%b+b)%b;
if (!x) x+=b;
ans+=c[i]*a*x;
}
ans=ksm(g,ans,mod);
printf("%lld",ans);
}