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;
}