[SDOI2010]古代猪文
一道数学题。
题解回去补
flag++
#include <cstdio>
#include <cmath>
long long n,g;
long long prime[4]= {2,3,4679,35617};
const long long mod=999911659;
int x[4];
long long fac[55555],inv[55555];
long long lucas(long long N,long long M,long long P) {
if(N<M){return 0;}
if(N<P&&M<P) {return fac[N]*inv[M]%P*inv[N-M]%P;}
return lucas(N%P,M%P,P)*lucas(N/P,M/P,P)%P;
}
long long work(long long p) {
fac[0]=1;
long long ans=0;
for(int i=1; i<p; i++) fac[i]=fac[i-1]*i%p;
inv[p-1]=p-1;
for(int i=p-2;~i;i--) inv[i]=inv[i+1]*(i+1)%p;
long long lim=sqrt(n);
for(int i=1; i<=lim; i++) {
if(n%i) continue;
ans=(ans+lucas(n,i,p))%p;
if(n/i==i)continue;
ans=(ans+lucas(n,n/i,p))%p;
}
return ans;
}
int exgcd(int a,int b,long long &x,long long &y) {
if(!b) {
x=1,y=0;
return a;
}
int ans=exgcd(b,a%b,x,y),t=x;
x=y,y=t-a/b*y;
return ans;
}
long long ksm(long long d,int z) {
long long res=1;
while(z) {
if(z&1) res=res*d%mod;
d=d*d%mod;
z>>=1;
}
return res;
}
void China() {
long long ans=0,xx,y;
for(int i=0; i<4; i++) {
long long t=(mod-1)/prime[i];
exgcd(prime[i],t,xx,y);
ans=(ans+y*t*x[i])%(mod-1);
if(ans<0) ans+=(mod-1);
}
printf("%lld",ksm(g,ans));
}
int main() {
scanf("%d%d",&n,&g);
if(g%mod==0) {
putchar('0');
return 0;
}
for(int i=0;i<4;i++)
x[i]=work(prime[i]);
China();
return 0;
}