求的是:
[g^xmod 999911659, ext{其中}x=sum_{dmid n} binom{n}{d}
]
由于这个(999911659)是质数,肯定于(g)互质,所以由欧拉定理很容易证明:
[a^{varphi(p)}equiv 1pmod pRightarrow a^{kmod varphi(p)}equiv a^kpmod p
]
那么可以得出:
[g^xmod 999911659equiv g^{xmod varphi(999911659)}pmod {999911659}
]
[g^xmod 999911659equiv g^{xmod 999911658}pmod {999911659}
]
所以问题转换为求:
[sum_{dmid n} binom{n}{d}mod 999911658
]
这种大组合数的问题考虑用 Lucas,但是模数太大,且不是质数
所以考虑将它分解:(999911658=2 imes 3 imes 4679 imes 35617)
那么,只需要对每一个质因数,求出(aequiv sum_{dmid n} binom{n}{d}mod p_i),然后再用 crt 合并就行了
算的时候,枚举每一个(ile sqrt n),如果(imid n),则计算( binom{n}{i})和( binom{n}{frac{n}{i}})加到答案里
但是,在这种因数不能重复计算的时候,要:
for(reg int i=1;i*i<=n;i++)
而不是
for(reg int i=1;i<=std::ceil(std::sqrt(n));i++)
对于后一种,举个栗子:(lceilsqrt {420} ceil=21),但是如果(i)一直枚举到(21),就会在(i=20,i=21)的时候算两次(20,21)这两个因数,重复了,出现错误
还有,因为每次的计算模数不同,所以要分别预处理
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<map>
#include<iomanip>
#include<cstring>
#define reg register
#define EN std::puts("")
#define LL long long
inline int read(){
register int x=0;register int y=1;
register char c=std::getchar();
while(c<'0'||c>'9'){if(c=='-') y=0;c=std::getchar();}
while(c>='0'&&c<='9'){x=x*10+(c^48);c=std::getchar();}
return y?x:-x;
}
const int prime[4]={2,3,4679,35617};
int fac[40006],inv[40005];
inline int power(int a,int b,int p){
int ret=1;
while(b){
if(b&1) ret=1ll*ret*a%p;
b>>=1;a=1ll*a*a%p;
}
return ret;
}
inline void pre(int n,int mod){
fac[0]=inv[0]=1;
for(reg int i=1;i<n;i++) fac[i]=(LL)fac[i-1]*i%mod;
inv[n-1]=power(fac[n-1],mod-2,mod);
for(reg int i=n-2;i;i--) inv[i]=(LL)inv[i+1]*(i+1)%mod;
}
inline int get_C(int n,int m,int mod){
//C(n,m)=n!/(m!*(n-m)!)
if(n<m) return 0;
return ((LL)fac[n]*inv[m]%mod)*inv[n-m]%mod;
}
inline int lucas(int n,int m,int mod){
if(n<m) return 0;
if(!n||!m) return 1;
return (LL)lucas(n/mod,m/mod,mod)*get_C(n%mod,m%mod,mod)%mod;
}
int main(){
// std::freopen("out.txt","w",stdout);
const int M=999911658;
int n=read(),g=read();
g%=(M+1);
if(!g) return std::puts("0"),0;
reg int ans=0,Mi,t;
for(reg int o=0;o<4;o++){
pre(prime[o],prime[o]);
reg int nowans=0;
for(reg int i=1;i*i<=n;i++)if(!(n%i)){
nowans=(nowans+lucas(n,i,prime[o]))%prime[o];
if(i*i!=n) nowans=((LL)nowans+lucas(n,n/i,prime[o]))%prime[o];
}
// std::printf("now ans = %d
",nowans);
// for(reg int i=0;i<prime[o];i++) std::printf("%d %d
",fac[i],inv[i]);
Mi=M/prime[o];
t=power(Mi,prime[o]-2,prime[o]);//t=Mi^{-1} mod prime[o]
ans=(ans+((LL)nowans*Mi%M*t%M))%M;
}
std::printf("%d",power(g,ans,M+1));
return 0;
}