求
\[2^{2^{2^{2^{2^{...}}}}}mod\,p \]\[p\leq 10^7 \]显然硬干是不行的,那么考虑别的思路。设 \(f(p)\) 为原式模 \(p\) 的解,那么 \(f(p)=2^{f(\varphi(p))+\varphi(x)}\) ,递归可以求出上一项的值即可,边界是 \(\varphi(p)=1\) 时 \(f(p)=0\) ,需要预处理出 \(\varphi\) 的值。
#include<bits/stdc++.h> using namespace std; #define ll long long int prime[10000005],phi[10000005],tot; bool not_prime[10000005]; int t,pp; void getp(){ phi[1]=1; for(int i=2;i<=10000000;++i){ if(not_prime[i]==0){ prime[++tot]=i; phi[i]=i-1; } for(int j=1;(prime[j]*i)<=10000000 && j<=tot;++j){ not_prime[i*prime[j]]=1; if((i%prime[j])==0){ phi[i*prime[j]]=phi[i]*prime[j]; break; } phi[i*prime[j]]=phi[i]*phi[prime[j]]; } } } ll Qpow(ll a,ll b,ll p){ ll ret=1; while(b){ if(b&1) ret=(ret*a)%p; b>>=1; a=(a*a)%p; } return ret; } ll f(ll x){ if(phi[x]==1) return 0; ll q=f(phi[x]); return Qpow(2,q+phi[x],x); } int main(){ getp(); scanf("%d",&t); while(t--){ scanf("%d",&pp); printf("%lld\n",f(pp)); } return 0; }