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;
}