[洛谷P4139]上帝与集合的正确用法
题目大意:多次询问,每次给你$p$询问$2^{2^{2^{\dots}}}\bmod p$
题解:扩展欧拉定理,求出$\varphi(p)$即可。因为$2^{2^{2^{\dots}}}>>p$,所以其实每一次算的时候都可以直接加上$\varphi(p)$,不用判断
卡点:无
C++ Code:
#include <cstdio> namespace Math { const int N = 1e7 + 1; int pri[N], ptot, phi[N]; bool notp[N]; inline void sieve() { phi[1] = 1; for (int i = 2; i < N; i++) { if (!notp[i]) phi[pri[ptot++] = i] = i - 1; for (int j = 0, t; j < ptot && (t = i * pri[j]) < N; j++) { notp[t] = true; if (i % pri[j] == 0) { phi[t] = phi[i] * pri[j]; break; } phi[t] = phi[i] * phi[pri[j]]; } } } inline long long pw(int b, int p, const int mod) { long long res = 1, base = b, tmp = 0; for (; p; p >>= 1) { if (p & 1) { res = res * base; if (res >= mod) tmp = mod, res %= mod; } base = base * base; if (base >= mod && p >> 1) tmp = mod, base %= mod; } return res + tmp; } } using Math::phi; int Tim, p; long long solve(int p) { if (p == 1) return p; return Math::pw(2, solve(phi[p]), p); } int main() { Math::sieve(); scanf("%d", &Tim); while (Tim --> 0) { scanf("%d", &p); printf("%lld\n", solve(p) % p); } return 0; }