2019ICPC南京網路賽B super_log——擴充套件尤拉定理

TeJoy發表於2020-11-14

和CF 906D的套路一樣
打表可知
x = a a a . . . ( m o d m ) x=a^{a^a...}(mod m) x=aaa...(modm) 總共 b b b a a a,特判 a = 1 a=1 a=1 b = 0 b=0 b=0的時候記得取模,然後沒了

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
unordered_map<int,ll>mp;
const int maxn=1e5+5;
int n,a,b,mo,q;
ll phi(int x){ //記得記搜 實在被卡常才上線性篩優化
    if(mp[x])return mp[x];
    int ans=x;int tmp=x;
    for(int i=2;i*i<=x;++i){ 
        if(x%i==0){ 
            ans=ans/i*(i-1);
            while(x%i==0)x/=i;
        }
    }
    if(x>1)ans=ans/x*(x-1);
    return mp[tmp]=ans;
}
ll Mod(ll x,ll m){ //擴充尤拉定理
    return x>=m?(x%m+m):x;
}
ll mypow(ll a,ll b,ll p){ 
    ll ans=1;
    while(b){ 
        if(b&1)ans=Mod(ans*a,p);//自定義取模
        a=Mod(a*a,p);
        b>>=1;
    }
    return ans;
}
ll solve(int l,ll m){ 
    if(l==1||m==1)return Mod(a,m);
    return mypow(a,solve(l-1,phi(m)),m);
}
int main(){ 
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin>>q;
    for(int i=1;i<=q;++i){ 
        cin>>a>>b>>mo;
        if(a==1){ cout<<1%mo<<"\n";continue;}//這裡也得模
        if(b==0){ cout<<1%mo<<"\n";continue;}//特判 記得取模
        cout<<solve(b,mo)%mo<<"\n";//記得最後取模
    }
    return 0;
}

相關文章