1. 程式人生 > >BZOJ 3884: 上帝與集合的正確用法

BZOJ 3884: 上帝與集合的正確用法

題目大意:求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; }