Luogu_P4139 上帝与集合的正确用法 扩展欧拉定理
Luogu_P4139 上帝与集合的正确用法
扩展欧拉定理
题目链接
扩展欧拉定理如下:
那这道题
\(2^{2^{2^{\dots}}}\bmod p\)
就是
\(2^{(2^{2^{\dots}}\bmod \varphi(p))+\varphi(p)}\bmod p\)
就可以递归求解了
当\(p=1\)就返回\(0\)
代码如下:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxp=1e7;
int phi[maxp+10];
inline ll sm(ll x,ll y,ll mod){
ll res=0;
while(y){
if(y&1) res=(res+x)%mod;
x=(x+x)%mod;y>>=1;
}
return res;
}
inline ll qp(ll x,ll y,ll mod){
ll res=1;
while(y){
if(y&1) res=sm(res,x,mod)%mod;
x=sm(x,x,mod)%mod;y>>=1;
}
return res;
}
inline ll sl(ll x){
if(x==1) return 0;
return qp(2,sl(phi[x])+phi[x],x);
}
int t,p;
int main()
{
for(int i=2;i<=maxp;i++) phi[i]=i;
for(int i=2;i<=maxp;i++)
if(phi[i]==i) for(int j=i;j<=maxp;j+=i)
phi[j]=phi[j]/i*(i-1);
scanf("%d",&t);
while(t--){
scanf("%d",&p);printf("%lld\n",sl((ll)p));
}
return 0;
}