[冪塔函數+歐拉降冪]2019ICPC南京網絡賽B super_log

https://www.jisuanke.com/contest/3004?view=challenges
要求的東西可以變成b+loga*(logabx)>=b,即loga*(logabx)>=0
顯然取等號最小
logabx=1是最小的滿足loga*(logabx)=0的值,此時x也是最小的
所以取logabx=1
轉換一下就變成了要求 x=aaa```,一共b個a

冪塔函數:aaa```
輸入a,b,m,求b層的a冪塔函數的值%m
類似例題:BZOJ3884
https://blog.csdn.net/syh0313/article/details/88977745
https://blog.csdn.net/qq_37632935/article/details/81264965

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e6+105;
ll T,primes[maxn],phi[maxn],cnt;
ll a,b,m,lim;
bool f[maxn];
ll tim[50];
ll po(ll a,ll b,ll mo){
    if(b==0) return 1%mo;
    if(b==1) return a%mo;
    ll c=po(a,b/2,mo);
    if (b&1) return c*c%mo*a%mo;else return c*c%mo;
}
ll solve2(ll d){
    if(d==0) return 1;
    return po(a,solve2(d-1),8e18);
}
ll solve(ll p,ll d){
    if (p==1) return 0;
    if(d==0) return 1%p;
    ll gcd=__gcd(a,p);//判斷a,p是否互質
    if(gcd==1){//a,p互質,歐拉定理
        return po(a,solve(phi[p],d-1),p);
    }else{//擴展歐拉定理的範疇
        if(d<33&&tim[d-1]<phi[p]){//b<phi(p)
            return po(a,solve2(d-1),p);
        }else{
            return po(a,solve(phi[p],d-1)+phi[p],p);
        }
    }
}
ll check(ll a,ll b){//判斷a^b有沒有>1e6
    ll ans=1;
    while(b){
        if(b&1){
            ans*=a;
            if(ans>1e6) return 1;
        }
        b>>=1;
        if(!b) break;//必須要有這句
        a=a*a;
        if(a>1e6||ans*a>1e6) return 1;
    }
    return 0;
}
int main(){
    memset(f,1,sizeof(f));
    f[1]=0;
    phi[1]=1;
    for (int i=2;i<=1e6;i++){
        if (f[i]) primes[++cnt]=i,phi[i]=i-1;
        for (int j=1;j<=cnt && i*primes[j]<=1e6;j++){
            f[i*primes[j]]=0;
            if (i%primes[j]==0) {phi[i*primes[j]]=phi[i]*primes[j]; break;}
            else phi[i*primes[j]]=phi[i]*phi[primes[j]];
        }
    }
    scanf("%lld",&T);
    while (T--){
        memset(tim,127,sizeof(tim));
        scanf("%lld%lld%lld",&a,&b,&m);
        ll tmp=a;
        tim[0]=1;
        for(int i=1;i<32;i++){
            tim[i]=tmp;//i層的a冪塔的值
            if(check(a,tmp)){//如果下一層>1e6了,說明a^b中b>phi(p)
                lim=i;break;
            }
            tmp=po(a,tmp,(ll)8e18);
        }
        printf("%lld\n",solve(m,b));
    }
    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章