标签:color tps lse += power else scan can names
题意:求G^M mod P,M=∑ i|N C(N,i),P=999911659。
思路:G^M mod P = G^(M mod (P-1) ) ( G != P),所以只要得出 M mod (P-1) 即可用快速幂求出答案
N的约数可以在√n的时间内求出,所以问题转化为求C(N,i) mod (P-1),发现p-1不是一个质数,P-1=2*3*4679*35617
只要求出C(N,i) mod 每个因数的值,得到4个取模方程,最后用中国剩余定理合并模线性方程组,求解。
#include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<map> #include<queue> #include<vector> #include<string> #include<set> #define ll long long using namespace std; const ll N=40005,P=999911659,M=P-1; ll n,G,a[8],m[8],fac[N],inv[N],fac_inv[N],res; ll power(ll a,ll b,ll mod) { ll c=1; for(;b;b>>=1) { if(b&1) c=(ll)c*a%mod; a=(ll)a*a%mod; } return c%mod; } ll C(ll n,ll m,ll MOD){ if(n<MOD&&m<MOD) return n<m?0:fac[n]*fac_inv[m]%MOD*fac_inv[n-m]%MOD; return C(n%MOD,m%MOD,MOD)*C(n/MOD,m/MOD,MOD)%MOD; } int main() { scanf("%lld%lld",&n,&G); G%=P; if(G==0) printf("0\n"); else { m[1]=2; m[2]=3; m[3]=4679; m[4]=35617; for(int k=1;k<=4;k++) { fac[0]=1; int u=m[k]+5; for(int i=1;i<=u;i++) fac[i]=fac[i-1]*i%m[k]; inv[1]=1; for(int i=2;i<=u;i++) inv[i]=(ll)(m[k]-m[k]/i)*inv[m[k]%i]%m[k]; fac_inv[0]=1; for(int i=1;i<=u;i++) fac_inv[i]=fac_inv[i-1]*inv[i]%m[k]; // printf("fac_inv:%lld\n",fac[3]); for(ll i=1;i*i<=n;i++) { if(n%i==0) { (a[k]+=C(n,i,m[k]))%=m[k]; if(i*i!=n) (a[k]+=C(n,n/i,m[k]))%=m[k]; } } // printf("a[k]:%lld\n",a[k]); (res+=a[k]*(M/m[k])%M*power(M/m[k],m[k]-2,m[k])%M)%=M; } // printf("res:%lld\n",res); printf("%lld\n",power(G,res,P)); } }
标签:color tps lse += power else scan can names
原文地址:https://www.cnblogs.com/2462478392Lee/p/11332781.html