题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=3884
题目大意:
给出 M, 求 $2^{2^{2^{2^{...}}}}$ % M 的值. p ≤ 1e9
题解:
我们设 M = $2^k$*p , p是奇数
$2^{2^{2^{2^{...}}}}$ % M = $2^k$ * ($2^{2^{2^{2^{...}}}-k}$ % p)
因为p是奇数,所以p与2互质,我们可以用欧拉定理
原式化为
可以递归地做下去
但模数变成1的时候直接返回0就好了
参考某大佬博客的时间复杂度:
AC代码如下:
#include<iostream> #include<cstring> #include<algorithm> #include<cstdio> using namespace std; typedef long long ll; int T; inline int read() { char ch=getchar(); int s=0,f=1; while (!(ch>='0'&&ch<='9')) {if (ch=='-') f=-1;ch=getchar();} while (ch>='0'&&ch<='9') {s=(s<<3)+(s<<1)+ch-'0';ch=getchar();} return s*f; } int qpow(ll a,int b,int m) { ll res=1; for (;b;b>>=1,a=a*a%m) if (b&1) res=res*a%m; return res%m; } int phi(int x) { int res=x; for (int i=2;i*i<=x;i++) { if (x%i) continue; res/=i;res*=i-1; while (x%i==0) x/=i; } if (x>1) res/=x,res*=x-1; return res; } int solve(int p) { if (p==1) return 0; int k=0; while (~p&1) p>>=1,k++; int phi_p=phi(p); int re=solve(phi_p); re=(re+phi_p-k%phi_p)%phi_p; re=qpow(2,re,p); return re<<k; } int main() { T=read(); while (T--) { int p=read(); printf("%d ",solve(p)); } return 0; }