[洛谷4139]上帝与集合的正确用法 题解

前言
非常interesting的题目,立个flag下一道做洛谷P3934 Nephren Ruq Insania
UPD(2019.5.21):flag完成了
解法
题目求\(2^{2^{2^{2\dots}}}\ \%\ p\)的值
珂以递归解决,根据欧拉降幂\(2^{2^{2^{2\dots}}}\ \%\ p\)转化为\(2^{2^{2^{2^{2\dots}}}\ \%\ phi[p] + phi[p]} % p\)
于是我们就愉快的递归解决,显然当递归到\(p\)\(1\)时,结果为\(0\),结束。

代码

#include <cstdio>
#define ll long long

inline ll read(){
    ll x = 0; int zf = 1; char ch = ' ';
    while (ch != '-' && (ch < '0' || ch > '9')) ch = getchar();
    if (ch == '-') zf = -1, ch = getchar();
    while (ch >= '0' && ch <= '9') x = x * 10 + ch - '0', ch = getchar(); return x * zf;
}

int phi[10000005];

ll getPhi(int MAXNUM){
    for(int i = 1; i <= MAXNUM; ++i)
        phi[i] = i;
    for(int i = 2; i <= MAXNUM; i += 2)
        phi[i] >>= 1;
    for(int i = 3; i <= MAXNUM; i += 2)
        if(phi[i] == i)
            for(int j = i; j <= MAXNUM; j += i)
                phi[j] = phi[j] / i * (i - 1);
}

ll pow(ll a, ll b, ll mod){
    if (!a) return 0;
    ll ans = 1;
    for ( ; b; b >>= 1, a = (a * a) % mod)
        if (b & 1)
            ans *= a, ans %= mod;
    return ans;
}

ll solve(ll mod){
    if (mod == 1) return 0;
    return pow(2, solve(phi[mod]) + phi[mod], mod);
}

int main(){
    getPhi(10000000);
    int T = read();
    for (int I = 0; I < T; ++I)
        printf("%lld\n", solve(read()));
    return 0;
}
posted @ 2019-05-20 20:35  LinZhengmin  阅读(211)  评论(0编辑  收藏  举报

Contact with me