【扩展欧拉定理】洛谷P4139 上帝与集合的正确用法

版权声明:虽然本蒟蒻很菜,但各位dalao转载请注明出处谢谢。 https://blog.csdn.net/xuxiayang/article/details/88719977

D e s c r i p t i o n Description

2 2 2 2 2 . . . m o d   p 2^{2^{2^{2^{2^{...}}}}} mod\ p
p 1 0 7 p\leq 10^7


S o l u t i o n Solution

根据扩展欧拉定理
a b { a b   m o d   φ ( p ) ) g c d ( a , p ) = 1 a b g c d ( a , p ) 1 , b < φ ( p ) ) a b   m o d   φ ( p ) + φ ( p ) ) g c d ( a , p ) 1 , b φ ( p ) } ( m o d   p ) a^b\equiv \begin{Bmatrix} a^{b\ mod\ \varphi(p))} & gcd(a,p)=1\\ a^b & gcd(a,p)\neq 1,b<\varphi(p))\\ a^{b\ mod\ \varphi(p)+\varphi(p))} & gcd(a,p)\neq 1,b\geq\varphi(p) \end{Bmatrix} (mod\ p)

根据第三条性质,我们就可以递归求 2 2 2 2 2 . . . 2^{2^{2^{2^{2^{...}}}}}

f ( p ) = 2 2 2 2 2 . . . m o d   p f(p)=2^{2^{2^{2^{2^{...}}}}} mod\ p ,得到 f ( p ) = 2 f ( φ ( p ) ) + φ ( p ) f(p)=2^{f(\varphi(p))+\varphi(p)}

φ ( p ) \varphi(p) 用线性筛即可


C o d e Code

#include<cstdio>
using namespace std;
const int N=1e7;
int t,phi[N+1],v[N+1],prime[N+1],m,p;
inline long long ksm (long long x,int y,int P)
{
	long long ans=1;
	for(;y;y>>=1,(x*=x)%=P) if(y&1) (ans*=x)%=P;
	return ans%p;
}
inline int solve(int x)
{
	if(x==1) return 0;
	return ksm(2,solve(phi[x])+phi[x],x);
}
signed main()
{
	scanf("%d",&t);
	phi[1]=1;
	for(register int i=2;i<=N;i++)
	{
		if(!v[i])
		{
			v[i]=i;prime[++m]=i;
			phi[i]=i-1;
		}
		for(register int j=1;j<=m;j++)
		{
			if(prime[j]>v[i]||prime[j]*i>N) break;
			v[i*prime[j]]=prime[j];
			phi[i*prime[j]]=phi[i]*(i%prime[j]?prime[j]-1:prime[j]);
		}
	}
	while(t--)
	{
		scanf("%d",&p);
		printf("%d\n",solve(p));
	}
}

猜你喜欢

转载自blog.csdn.net/xuxiayang/article/details/88719977