原题链接
思路:
由扩展欧拉定理,有:
\[
2^{2^{2\cdots}} \equiv 2^{(2^{2\cdots} \mod \varphi(p)) +
\varphi(p)}\pmod p
\]
上面的 \(2^{2\cdots} \mod
\varphi(p)\) 可以递归求解,当 \(\varphi(p)\) 减小到 1 即可回溯.
至于 \(\varphi(p)\),
用线性筛预处理即可.
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
| #include <cstdio> #include <vector> using namespace std; const int Mp(10000050); int phi[Mp]; vector<int> prm; void euler() { phi[1] = 0; for(int i(2);i<Mp;++i) { if(!phi[i]) { phi[i] = i-1; prm.push_back(i); } for(int j(0);j<prm.size() && 1ll*i*prm[j]<Mp;++j) { if(i%prm[j]==0) { phi[i*prm[j]] = phi[i]*prm[j]; break; } else { phi[i*prm[j]] = phi[i]*(prm[j]-1); } } } }
int ksm(int a,int b,int p) { int ret(1),tmp(a%p); for(int i(0);(1<<i)<=b;++i) { if(b&(1<<i)) { ret = 1ll*ret*tmp%p; } tmp = 1ll*tmp*tmp%p; } return ret; } int ans(int p) { if(p<=1) { return 0; } else { return ksm(2,ans(phi[p])+phi[p],p); } }
int main() { euler(); int T; scanf("%d",&T); while(T--) { int n; scanf("%d",&n); printf("%d\n",ans(n)); } return 0; }
|