一本通OJ-古代猪文
古代猪文
题意
求\(g^{\sum C_{n}^{k} \mod{999911659}}\)满足\(k\mid n\)。
分析
由题意,可以先枚举这样的k。
for(int i=1;i*i<=mod;i++)
if(mod%i==0){
if(i*i!=mod) //mod/i;
//i
}
而后,由欧拉定理的推论得\(a^b\equiv a^{b\mod{φ(p)}}\pmod{p}\)。\(φ(p)=从1到p-1与p互质的个数\)。
因为\(999911658=2*3*4679*35617\),因而
则可令
\(a_1=\sum k\mid n\) \(C_{n}^{k} \mod {2}\)
\(a_2=\sum k\mid n\) \(C_{n}^{k} \mod {3}\)
\(a_3=\sum k\mid n\) \(C_{n}^{k} \mod {4679}\)
\(a_4=\sum k\mid n\) \(C_{n}^{k} \mod {35617}\)
则通过\(Lucas\)定理可求得\(a_1,a_2,a_3,a_4\)。
则求得的
\(x\equiv a_1 \pmod {2}\)
\(x\equiv a_2 \pmod {3}\)
\(x\equiv a_3 \pmod {4679}\)
\(x\equiv a_4 \pmod {35617}\)
则可以使用CRT来求解\(x\)。
则令\(k=\prod\limits_{i=1}^nb_i\),\(x=\sum\limits_{i=1}^n(\frac{k}{b[i]})^{b_{i}-1}*a[i]*k\mod {b[i]}\)。
对于本题\(k=999911658\)。
代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=1e6+7;
int fac[N],inv[N],mod;
int b[5]={0,2,3,4679,35617};
int a[50];
int qpow(int shu,int cifang,int mod){
int ans=1;
int k=cifang;
while(k){
if(k&1){
ans=ans*shu%mod;
shu=shu*shu%mod;
}
else{
shu=shu*shu%mod;
}
k>>=1;
}
return ans%mod;
}
void init(int p){
fac[0]=inv[0]=fac[1]=inv[1]=1;
for(int i=2;i<=p;i++){
fac[i]=fac[i-1]*i%p;
inv[i]=((p-p/i)*inv[p%i]+p)%p;
}
for(int i=2;i<=p;i++) inv[i]=inv[i-1]*inv[i]%p;
}
int C(int n,int m){
if(n<m) return 0;
return fac[n]*inv[m]%mod*inv[n-m]%mod;
}
int lucas(int n,int m,int p){
if(n<m) return 0;
if(m==0) return 1;
else return C(n%p,m%p)*lucas(n/p,m/p,p)%p;
}
int x;
int n,g;
int ans;
void crt(){
for(int i=1;i<=4;i++)x=(x+a[i]*(mod/b[i])%mod*qpow(mod/b[i],b[i]-2,b[i]))%mod;
}
signed main(){
scanf("%lld%lld",&n,&g);
mod=999911658;
if(g%(mod+1)==0) return printf("0"),0;
for(int k=1;k<=4;k++){
init(b[k]);
for(int i=1;i*i<=n;i++){
if(n%i==0){
a[k]=(a[k]+lucas(n,i,b[k]))%b[k];
if(i*i!=n) a[k]=(a[k]+lucas(n,n/i,b[k])%b[k]);
}
}
}
crt();
ans=qpow(g,x,mod+1);
printf("%lld",ans);
return 0;
}