题目大意:
求2^(2^(2^...))%p的值,每次给定p。
题解:
扩展欧拉定理
a^n=a^(n%phi(p)+phi(p)) (mod p)
设f(p)为模数为p时候这个式子的答案。
f(p)=2^(f(phi(p))+phi(p))
然后递归暴力,因为每次取phi,不会递归很多层
代码:
#include<cstdio>
using namespace std;
int cnt,isprime[10000005],prime[2000005],phi[10000005];
int pow(int a,int b,int mod){
int ans=1;
while (b){
if (b&1) ans=1ll*ans*a%mod;
a=1ll*a*a%mod;
b=b>>1;
}
return ans;
}
long long calc(int mod){
if (mod==1) return 0;
return pow(2,calc(phi[mod])+phi[mod],mod);
}
int main(){
int t;
scanf("%d",&t);
for (int i=2; i<=10000000; i++){
if (!isprime[i]){
prime[++cnt]=i;
phi[i]=i-1;
}
for (int j=1; j<=cnt && i*prime[j]<=10000000; j++){
isprime[i*prime[j]]=1;
if (i%prime[j]==0){
phi[i*prime[j]]=phi[i]*prime[j];
break;
}
else phi[i*prime[j]]=phi[i]*(prime[j]-1);
}
}
while (t--){
int mod;
scanf("%d",&mod);
printf("%d
",calc(mod));
}
return 0;
}