Luogu 4139 上帝与集合的正确用法
扩展欧拉定理:$a^{b} \equiv a^{b Mod \varphi (p) + \varphi (p)} (Mod p) $ $(b \geq \varphi (p))$ 。
这道题中$\varphi (p)$一定是一个偶数,所以余数为$0$。
这样子的话只需要递归求解就可以了,可以知道一定不会超过$log$层。
时间复杂度$O(maxN + Tlognlogn)$。
Code:
#include <cstdio> #include <cstring> using namespace std; typedef long long ll; const int N = 1e7 + 5; int testCase, pCnt, pri[N]; ll n, phi[N]; bool np[N]; template <typename T> inline void read(T &X) { X = 0; char ch = 0; T op = 1; for(; ch > '9'|| ch < '0'; ch = getchar()) if(ch == '-') op = -1; for(; ch >= '0' && ch <= '9'; ch = getchar()) X = (X << 3) + (X << 1) + ch - 48; X *= op; } void sieve() { phi[1] = 1LL; for(int i = 2; i < N; i++) { if(!np[i]) pri[++pCnt] = i, phi[i] = i - 1; for(int j = 1; j <= pCnt && i * pri[j] < N; j++) { np[i * pri[j]] = 1; if(i % pri[j] == 0) { phi[i * pri[j]] = phi[i] * pri[j]; break; } phi[i * pri[j]] = phi[i] * (pri[j] - 1); } } } inline ll pow(ll a, ll b, ll P) { ll res = 1LL; for(; b > 0; b >>= 1) { if(b & 1) res = res * a % P; a = a * a % P; } return res; } ll solve(ll now) { if(now == 1) return 0; return pow(2LL, phi[now] + solve(phi[now]), now); } int main() { sieve(); for(read(testCase); testCase--; ) { read(n); printf("%lld\n", solve(n)); } return 0; }