P4139 上帝与集合的正确用法

思路:扩展欧拉定理

提交:(1)

题解:

首先简介扩展欧拉定理:
(b>=varphi(p))时,(a^bequiv a^{b\%varphi(p)+varphi(p)} mod p)
这样我们可以递归去算这个式子,直到(p==1),因为(2^{2^{2^cdots}})永远是无穷大的。

代码:

#include<cstdio>
#include<iostream>
#define ll long long
#define R register ll
using namespace std;
namespace Luitaryi {
template<class I> inline I g(I& x) { x=0;
	register I f=1; register char ch; while(!isdigit(ch=getchar())) f=ch=='-'?-1:f;
	do x=x*10+(ch^48); while(isdigit(ch=getchar())); return x*=f;
} const int N=1e7+10;
int T,x,cnt,p[N>>1],phi[N];
bool v[N];
inline void PRE() { phi[1]=1;
	for(register int i=2;i<=N-10;++i) {
		if(!v[i]) p[++cnt]=i,phi[i]=i-1;
		for(register int j=1;j<=cnt&&i*p[j]<=N-10;++j) {
			v[i*p[j]]=true;
			if(i%p[j]==0) {
				phi[i*p[j]]=phi[i]*p[j]; break;
			} phi[i*p[j]]=phi[i]*(p[j]-1);
		}
	} 
} 
inline int qpow(int p,int M) { R a=2,ret=1;
	for(;p;p>>=1,(a*=a)%=M) if(p&1) (ret*=a)%=M; return ret;
}
inline int calc(int x) {
	if(x==1) return 0;
	return qpow(phi[x]+calc(phi[x]),x);
}
inline void main() {
	PRE(); g(T); while(T--) {
		g(x); printf("%d
",calc(x));
	}
}
} signed main() {Luitaryi::main(); return 0;}

2019.08.23
77

原文地址:https://www.cnblogs.com/Jackpei/p/11401388.html