题目大意:给定N,G,求
首先由欧拉定理易知当A与p互质时A^B %p=A^(B%φ(p) ) %p
这里p是一个质数 于是φ(p)=p-1=999911658
然后由于这个数不是质数 难以处理 我们将它分解质因数 然后对于每个质因数的解用中国剩余定理合并即可
然后就是999911658有一个很好的性质 999911658=2*3*4679*35617 每个质因数的次数都是1次
于是我们可以套用卢卡斯定理 预先处理出对于每个质因数的阶乘和阶乘的逆元即可
注意此题有个细节 就是欧拉定理中a与p必须互质 而当a=0(即G=p)时gcd(a,p)=p
所以有一组数据是专门卡这个地方的 这组数据是999911657 999911659 取模后是0^0 于是得到1 但是答案是0
于是我们做一些处理 A^B %p=A^(B%φ(p)+φ(p) ) %p
这样就没问题了
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define Mo 999911659 #define Phi_Mo 999911658 using namespace std; typedef long long ll; typedef pair<ll,ll> abcd; ll prime[4]={2,3,4679,35617}; ll n,g,ans[5]; ll factorial[4][35617],inverse[4][35617]; void Linear_Shaker(ll p,ll fac[],ll inv[]) { ll i; fac[0]=1; for(i=1;i<p;i++) fac[i]=fac[i-1]*i%p; inv[1]=1; for(i=2;i<p;i++) inv[i]=(p-p/i)*inv[p%i]%p; inv[0]=1; for(i=1;i<=p;i++) inv[i]=inv[i]*inv[i-1]%p; } ll C(ll n,ll m,ll p,ll fac[],ll inv[]) { if(n<m) return 0; if(n<p&&m<p) return fac[n]*inv[m]%p*inv[n-m]%p; return C(n%p,m%p,p,fac,inv)*C(n/p,m/p,p,fac,inv)%p; } inline void Calculate(ll x) { int i; for(i=0;i<4;i++) { ans[i]+=C(n,x,prime[i],factorial[i],inverse[i]); ans[i]%=prime[i]; } } abcd EXGCD(ll x,ll y) { if(!y) return abcd(1,0); abcd temp=EXGCD(y,x%y); return abcd(temp.second,temp.first-x/y*temp.second); } ll Chinese_Remainder_Theorem() { int i; ll re=0; for(i=0;i<4;i++) { abcd temp=EXGCD( Phi_Mo/prime[i] , prime[i] ); ll x=(temp.first%Phi_Mo*(Phi_Mo/prime[i])%Phi_Mo+Phi_Mo)%Phi_Mo; re+=x*ans[i]%Phi_Mo; re%=Phi_Mo; } return re; } ll Quick_Power(ll x,ll y) { ll re=1; while(y) { if(y&1)re*=x,re%=Mo; x*=x,x%=Mo; y>>=1; } return re; } int main() { //freopen("1951.in","r",stdin); //freopen("1951.out","w",stdout); ll i; for(i=0;i<4;i++) Linear_Shaker(prime[i],factorial[i],inverse[i]); cin>>n>>g; for(i=1;i*i<n;i++) if(n%i==0) Calculate(i),Calculate(n/i); if(i*i==n) Calculate(i); ans[4]=Chinese_Remainder_Theorem(); ans[4]=Quick_Power(g%Mo,ans[4]+Phi_Mo); cout<<ans[4]<<endl; }