bzoj 3884
直接利用降幂公式(或者有人叫扩展欧拉定理?),由降幂公式:
那么我们可以对这个式子降幂:
发现指数部分仍然是原表达式的形式,所以我们递归处理:
记f(p)=2^2^2^2^2... mod p
于是根据上述分析可得:
f(p)=2^(f(φ(p)+φ(p)) mod p
于是我们不断递归至φ(p)=1,此时f(φ(p))=0为止即可
#include <cstdio> #include <cmath> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> #include <queue> #include <stack> #define maxn 10000005 #define maxN 10000000 #define ll long long using namespace std; int prime[6000000]; bool used[maxn]; int phi[maxn]; int cnt=0; void eular() { for(int i=2;i<=maxN;i++) { if(used[i]==0) { prime[++cnt]=i; phi[i]=i-1; } for(int j=1;j<=cnt&&i*prime[j]<=maxN;j++) { used[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); } } } } ll pow(ll x,ll y,ll mod) { ll ans=1; while(y) { if(y%2==1) { ans=ans*x%mod; } y/=2; x=x*x%mod; } return ans%mod; } ll f(ll c) { if(c==1) { return 0; } return pow(2,f(phi[c])+phi[c],c)%c; } int main() { eular(); int t; scanf("%d",&t); for(int i=1;i<=t;i++) { ll p; scanf("%lld",&p); printf("%lld\n",f(p)); } return 0; }