2019ICPC南京網絡賽B super_log


題意:求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;
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM