题目大意:求2的2的2的2的。。。。(无穷多个)次方对p取模的值。
题解:
扩展欧拉定理有(a^b)%p=(a^(b%phi(p)+phi(p)))%p,不停递归下去知道p等于1,这样的话不会超过2*log(n)层,最简单的证明:奇数取phi最小减一,偶数最小减一半。
#include<iostream>
#include<iomanip>
#include<ctime>
#include<cmath>
#include<cstring>
#include<string>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
using namespace std;
int get_phi(int p)
{
int ans=p;
int i;
int yuan=p;
for(i=2;i*i<=yuan;i++)
{
if(p==1) break;
if(p%i==0)
{
ans-=ans/i;
while(p%i==0) p/=i;
}
}
if(p!=1) ans-=ans/p;
return ans;
}
long long ksm(long long x,int t,int p)
{
long long re=1;
while(t)
{
if(t&1) re=re*x%p;
x=x*x%p;
t>>=1;
}
return re;
}
int get_ans(int p)
{
if(p==1) return 0;
int phi=get_phi(p);
return ksm(2,get_ans(phi)+phi,p);
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int x;
scanf("%d",&x);
printf("%d\n",get_ans(x));
}
return 0;
}