BZOJ3884 上帝与集合的正确用法

题目链接:戳我

递归+拓展欧拉定理

因为指数非常大,所以我们可以直接套用拓展欧拉定理,递归地计算下去。

如果p=1的时候就停止,直接返回0即可。

代码如下:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define MAXN 100010
using namespace std;
int t;
long long P;
inline long long fpow(long long x,long long y,long long p)
{
    long long cur_ans=1;
    while(y)
    {
        if(y&1) cur_ans=1ll*cur_ans*x%p;
        x=1ll*x*x%p;
        y>>=1;
    }
    return cur_ans;
}
inline long long phi(long long x)
{
    long long cur_ans=x,now=x;
    for(int i=2;i*i<=now;i++)
    {
        if(now%i==0) cur_ans=cur_ans*(i-1)/i;
        while(now%i==0) now/=i;
    }
    if(now>1) cur_ans=cur_ans*(now-1)/now;
    return cur_ans;
}
inline long long solve(long long x)
{
    if(x<=1) return 0;
    long long cur=phi(x);
    return fpow(2,solve(cur)+cur,x);
}
int main()
{
    #ifndef ONLINE_JUDGE
    freopen("ce.in","r",stdin);
    #endif 
    scanf("%d",&t);
    while(t--)
    {
        scanf("%lld",&P);
        printf("%lld\n",solve(P));
    }
    return 0;
}
posted @ 2019-03-09 22:21  风浔凌  阅读(199)  评论(0编辑  收藏  举报