擴充套件尤拉定理--luoguP4139 上帝與集合的正確用法
阿新 • • 發佈:2018-12-13
擴充套件尤拉定理
據說可以用來解決迴圈節問題
迴圈又分純迴圈和混迴圈
純迴圈:
如ax%b 它的迴圈節就是b/gcd(a,b),那麼x在[0,b)之內就有gcd(a,b)個取值
(a,b互質就是純迴圈,不互質就是混迴圈)
混迴圈:
迴圈節前面的一段尾巴來自於共有的約數p,是log級別的
迴圈節長度是phi(b)的約數
這道題就是一個擴充套件尤拉定理的應用
當a,b互質的時候它是一個純迴圈,就可以直接把指數不斷%phi(p)
當a,b不互質的時候,要把指數%phi(p)再加上phi(p)(當指數大於phi(p)時)
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<cmath> #define maxn 1000001 #define LL long long using namespace std; int t,p,cnt; LL pri[700000],phi[maxn]; bool vis[maxn]; inline int rd(){ int x=0,f=1;char c=' '; while(c<'0' || c>'9') f=c=='-'?-1:1,c=getchar(); while(c<='9' && c>='0') x=x*10+c-'0',c=getchar(); return x*f; } inline void get_phi(){ vis[1]=1; phi[1]=1; for(int i=2;i<maxn;i++){ if(!vis[i]) pri[++cnt]=i,phi[i]=i-1; for(int j=1;j<=cnt && i*pri[j]<maxn;j++){ vis[i*pri[j]]=1; if(i%pri[j]==0){ phi[i*pri[j]]=phi[i]*pri[j]; break; } phi[i*pri[j]]=phi[i]*(pri[j]-1); } } } inline LL qpow(LL x,int k,int mod){ LL ret=1; while(k){ if(k&1) (ret*=x)%=mod; (x*=x)%=mod; k>>=1; } return ret; } inline LL solve(int p){ if(p==1) return 0; return qpow(2,solve(phi[p])+phi[p],p); } int main(){ t=rd(); get_phi(); cout<<cnt<<endl; while(t--){ p=rd(); printf("%lld\n",solve(p)); } return 0; }