BZOJ 3884: 上帝与集合的正确用法 扩展欧拉定理 + 快速幂
求 $2^{2^{2^{2...}}}$ 即 $2^{2^\infty }$
有扩展欧拉定理 : $2^{b} \equiv2^{b\%\varphi(x)+\varphi(x)}$$(b\geq\varphi(x))$
在这道题中,$b$ 始终为 $2^{2^{\infty}}$, 大小并不会减小.
好在 $\varphi(x)$ 的值会不断变小.
递归出口为 $x=1$,这样值就为 1 了.
有扩展欧拉定理 : $2^{b} \equiv2^{b\%\varphi(x)+\varphi(x)}$$(b\geq\varphi(x))$
在这道题中,$b$ 始终为 $2^{2^{\infty}}$, 大小并不会减小.
好在 $\varphi(x)$ 的值会不断变小.
递归出口为 $x=1$,这样值就为 1 了.
#include<bits/stdc++.h> #define maxn 10000004 #define ll long long using namespace std; void setIO(string s) { string in=s+".in"; freopen(in.c_str(),"r",stdin); } int cnt; int phi[maxn],vis[maxn],prime[maxn]; ll qpow(ll a,ll k,ll mod) { ll tmp=1; while(k) { if(k&1)tmp=(tmp*a)%mod; k>>=1; a=(a*a)%mod; } return tmp; } ll solve(int p) { if(p==1) return 0; return qpow(2, solve(phi[p]) + phi[p], p); } int main() { int i,j,T,p; // setIO("input"); for(i=2;i<maxn;++i) { if(!vis[i]) prime[++cnt]=i,phi[i]=i-1; for(j=1;j<=cnt&&1ll*prime[j]*i<maxn;++j) { vis[prime[j]*i]=1; if(i%prime[j]!=0) phi[i*prime[j]]=phi[i]*(prime[j]-1); else { phi[i*prime[j]]=phi[i]*prime[j]; break; } } } scanf("%d",&T); while(T--) { scanf("%d",&p); printf("%lld\n",solve(p)); } return 0; }