題意:求a的a的a次方。。一直求b次,也就是在紙上寫個a,然后一直a次方a次方,對m取模,記為F(a,b,m)=pow(a,F(a,b-1,phi(m))
解題思路:聯系歐拉降冪,這個迭代的過程,我們是一直對m求歐拉函數,然后在對這個結果求歐拉函數,顯然這個過程迭代次數不會多,驗證可得1e6范圍內最多迭代19次,
但是這個題有個坑,快速冪必須取mod后+mod,才不會出現結果為0的情況,為0會導致有些情況不對(wa)
AC代碼:
#include<bits/stdc++.h> using namespace std; const int maxn=1e6+5; typedef long long ll; bitset<maxn>notprime; int phi[maxn],prime[maxn],cnt=0; void pre(){ phi[1]=1; for(int i=2;i<=maxn-5;i++){ if(!notprime[i]){ prime[++cnt]=i; phi[i]=i-1;//i為素數時,phi[i]=i-1 } for(int j=1;j<=cnt&&prime[j]*i<=maxn;j++){ notprime[i*prime[j]]=1; if(i%prime[j]==0){//每個數只被它的最小質因數給篩掉 phi[i*prime[j]]=phi[i]*prime[j]; //當a與b互質時,滿足phi(a∗b)=phi(a)∗phi(b),積性函數 break; } else phi[i*prime[j]]=phi[i]*(prime[j]-1); //phi[i∗prime[j]]=phi[i]∗phi[prime[j]]=phi[i]∗(prime[j]−1); } } } ll quick_mod(ll a,ll n,ll mod) { ll res=1; while (n) { if(n&1)res=res*a>mod?res*a%mod+mod:res*a; a=a*a>mod?a*a%mod+mod:a*a; n>>=1; } return res; } ll deal(ll a,ll b,ll m) { if(b==0)return 1; if(m==1)return 1; ll res=deal(a,b-1,phi[m]); return quick_mod(a,res,m); } int main(){ pre(); int t; cin>>t; ll a,b,m; while (t--) { cin>>a>>b>>m; cout<<deal(a,b,m)%m<<endl; } }