【bzoj3884】上帝与集合的正确用法 【欧拉函数】
题目传送门
题解
这道题其实就是一个欧拉函数的性质的应用:
若且,则。
我们设,,。
则
我们令
则
于是我们只需要递归计算即可。当就返回。
答案就是。
代码
#include<cstdio>
#define int long long
int t,p;
int calcphi(int n){
if(n==1||n==2){
return 1;
}
int res=n;
for(int i=2;i*i<=n;i++){
if(n%i==0){
res=res/i*(i-1);
while(n%i==0){
n/=i;
}
}
}
if(n!=1){
res=res/n*(n-1);
}
return res;
}
int fastpow(int a,int x){
int res=1;
while(x){
if(x&1){
res*=a;
}
x>>=1;
a*=a;
}
return res;
}
int fastpow2(int a,int x,int mod){
int res=1;
while(x){
if(x&1){
res=res*a%mod;
}
x>>=1;
a=a*a%mod;
}
return res;
}
int solve(int i,int j){
if(j==1){
return 0;
}
int u=0,tmp=j;
while(!(tmp&1)){
u++;
tmp>>=1;
}
int phi=calcphi(tmp);
return (fastpow(2,u)*(fastpow2(2,solve(u,phi)+phi,tmp)%tmp)%j-i%j+j)%j;
}
signed main(){
scanf("%lld",&t);
while(t--){
scanf("%lld",&p);
printf("%lld\n",solve(0,p));
}
return 0;
}