【bzoj3884】上帝与集合的正确用法
【题目大意】
求2^(2^(2^(2^(2^...)))) mod p的值
【题解】
这是道神题。
来自PoPoQQQ大爷的题解
1 /************* 2 bzoj 3884 3 by chty 4 2016.11.4 5 *************/ 6 #include<iostream> 7 #include<cstdio> 8 #include<cstring> 9 #include<cstdlib> 10 #include<ctime> 11 #include<cmath> 12 #include<algorithm> 13 using namespace std; 14 typedef long long ll; 15 inline ll read() 16 { 17 ll x=0,f=1; char ch=getchar(); 18 while(!isdigit(ch)) {if(ch=='-') f=-1; ch=getchar();} 19 while(isdigit(ch)) {x=x*10+ch-'0'; ch=getchar();} 20 return x*f; 21 } 22 ll fast(ll a,ll b,ll mod){ll ans=1;while(b){if(b&1)ans=ans*a%mod;b/=2;a=a*a%mod;}return ans;} 23 ll get(ll x) 24 { 25 ll sum=x; 26 for(ll i=2;i*i<=x;i++) 27 if(x%i==0) 28 { 29 sum=sum/i*(i-1); 30 while(x%i==0) x/=i; 31 } 32 if(x>1) sum=sum/x*(x-1); 33 return sum; 34 } 35 ll solve(ll p) 36 { 37 if(p==1) return 0; 38 ll temp=0; 39 while(~p&1) p/=2,temp++; 40 ll phi=get(p); 41 ll re=solve(phi); 42 re=(re+phi-temp%phi)%phi; 43 re=(fast(2,re,p))%p; 44 return re<<temp; 45 } 46 int main() 47 { 48 freopen("cin.in","r",stdin); 49 freopen("cout.out","w",stdout); 50 ll T=read(); 51 while(T--) 52 { 53 ll p=read(); 54 printf("%lld\n",solve(p)); 55 } 56 return 0; 57 }