[扩展欧拉定理]luogu P4139 上帝与集合的正确用法
https://www.luogu.org/problem/P4139
分析
今天写了个毒瘤题,回来记录一下这个入门先
题目要求$2^{2^{2^{2^{...}}}} Mod\: p$
先说扩展欧拉定理
对于任意$a$大于等于$\varphi (p)$,有
$c^{a} Mod\: p=c^{a Mod\: \varphi (p)\: +\varphi (p)} Mod\: p$
如果$a$小于$p$则有
$c^{a} Mod\: p=c^{a Mod\: \varphi (p)} Mod\: p$
然后这题是无限指数,所以肯定满足a≥phi(p),所以直接递归到p=1的时候返回即可
用积性筛处理欧拉函数即可
#include <iostream> #include <cstdio> using namespace std; typedef long long ll; const int N=1e7+1; int t,phi[N],p,prime[N],pcnt; bool b[N]; void Prime() { phi[1]=1; for (int i=2;i<N;i++) { if (!b[i]) phi[i]=i-1,prime[++pcnt]=i; for (int j=1;j<=pcnt;j++) { if (prime[j]*i>=N) break; b[i*prime[j]]=1; if (i%prime[j]==0) {phi[i*prime[j]]=phi[i]*prime[j];break;} phi[i*prime[j]]=phi[i]*(prime[j]-1); } } } ll Pow(int x,int y,int p) {ll ans=1;for (;y;y>>=1,x=1ll*x*x%p) if (y&1) ans=ans*x%p; return ans;} ll Solve(int p) {return p==1?0:Pow(2,Solve(phi[p])+phi[p],p);} int main() { Prime(); for (scanf("%d",&t);t;t--) { scanf("%d",&p); printf("%lld\n",Solve(p)); } }
在日渐沉没的世界里,我发现了你。