此题用到的公式:a^b%c=a^(b%phi(c)+phi(c))%c (b>=phi(c)).
1.当n!<phi(p)时,直接暴力掉;
2.当n!>=phi(p) && n!%phi(p)!=0,用上面公式求;
3.当n!>=phi(p) && n!%phi(p)==0,变为n^(phi(p))%p,找循环节,就可以了
1 #include<iostream> 2 #include<stdio.h> 3 #include<algorithm> 4 #include<iomanip> 5 #include<cmath> 6 #include<string> 7 #include<cstdlib> 8 #include<vector> 9 #define ll unsigned __int64 10 using namespace std; 11 ll an[100001]; 12 ll euler(ll n) 13 { 14 ll ans=1; 15 for(int i=2;i*i<=n;i++) 16 { 17 if(n%i==0) 18 { 19 ans*=i-1; 20 n/=i; 21 while(n%i==0) 22 { 23 ans*=i; 24 n/=i; 25 } 26 } 27 } 28 if(n>1) ans*=n-1; 29 return ans; 30 } 31 ll pows(ll a,ll b, ll mod) 32 { 33 ll ans=1; 34 while(b) 35 { 36 if(b&1) ans=(ans*a)%mod; 37 b>>=1; 38 a=(a*a)%mod; 39 } 40 return ans%mod; 41 } 42 int main() 43 { 44 int t,k=0; 45 ll m,ans,fac,c,i,j,phi,b,p; 46 cin>>t; 47 while(t--) 48 { 49 scanf("%I64u%I64u%I64u",&b,&p,&m); 50 printf("Case #%d: ",++k); 51 if(p==1) 52 { 53 if(m==18446744073709551615U) 54 printf("18446744073709551616 "); 55 else printf("%I64u ",m+1); 56 continue; 57 } 58 ans=0;fac=1; 59 phi=euler(p); 60 //n!<phi(p) 61 for(i=0;i<=m&&fac<=phi;i++) 62 { 63 if(pows(i,fac,p)==b) 64 ans++; 65 fac*=(i+1); 66 } 67 fac%=phi; 68 //n!>=phi(p) && n!%phi(p)!=0 69 for(;i<=m&&fac;i++) 70 { 71 if(pows(i,fac+phi,p)==b) 72 ans++; 73 fac=(fac*(i+1))%phi; 74 } 75 //n!>=phi(p) && n!%phi(p)==0 76 if(i<=m) 77 { 78 ll cnt=0; 79 // memset(an,0,sizeof(an)); 80 for(j=0;j<p;j++) 81 { 82 an[j]=pows(i+j,phi,p); 83 if(an[j]==b) 84 cnt++; 85 } 86 c=(m-i+1)/p; 87 ans+=c*cnt; 88 ll remind=(m-i+1)%p; 89 for(j=0;j<remind;j++) 90 if(an[j]==b) 91 ans++; 92 } 93 printf("%I64u ",ans); 94 } 95 return 0; 96 }