[P4139]上帝与集合的正确用法

Description:


\(\huge2^{2^{2^{2^{....}}}} mod_p\)

Solution:

递归使用欧拉定理求解即可

#include <map>
#include <set>
#include <stack>
#include <cmath>
#include <queue>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#define ls p<<1 
#define rs p<<1|1
using namespace std;
typedef long long ll;
const ll mxn=1e7+5;
ll tot,n,m,mod,cnt;

inline ll read() {
    char c=getchar(); ll x=0,f=1;
    while(c>'9'||c<'0') {if(c=='-') f=-1;c=getchar();}
    while(c<='9'&&c>='0') {x=(x<<3)+(x<<1)+(c&15);c=getchar();}
    return x*f;
}
inline void chkmax(ll &x,ll y) {if(x<y) x=y;}
inline void chkmin(ll &x,ll y) {if(x>y) x=y;}




int vis[mxn+5],p[1000000],ph[mxn+5];

ll qpow(ll a,ll b,ll p) {
    ll res=1,bs=a;
    while(b) {
        if(b&1) res=1ll*res*bs%p;
        bs=1ll*bs*bs%p;
        b>>=1;
    }
    return res;
}

void sieve() {
    vis[1]=ph[1]=1;
    for(ll i=2;i<=mxn;++i) {
        if(!vis[i]) ph[i]=i-1,p[++tot]=i;
        for(ll j=1;j<=tot&&i*p[j]<=mxn;++j) {
            vis[p[j]*i]=1;
            if(i%p[j]==0) {
                ph[p[j]*i]=p[j]*ph[i];
                break;
            }
            else ph[p[j]*i]=ph[p[j]]*ph[i];
        }
    }
}

ll solve(ll x) {
    if(x==1) return 0;
    return qpow(2,solve(ph[x])+ph[x],x);
}

int main()
{
    ll T; T=read(); sieve();
    while(T--) {
        mod=read(); printf("%lld\n",solve(mod));
    }
    return 0;
}

posted @ 2019-04-02 15:37  cloud_9  阅读(90)  评论(0编辑  收藏  举报