求素数p的原根

定义: 设m>1,gcd(a,m)=1,使得a^{d}equiv 1(mod m)成立的最小正整数d为a对模m的阶,记为δm(a)

如果δm(a)=φ(m),则称a是模m的原根

定理:设m>1,gcd(a,m)=1,那么正整数x是同于方程a^{x}equiv 1 mod(n)的一个解的一个根当且仅当δm(a) | x

定理:由欧拉定理得  gcd(a,n)=1

定理:模m有原根的充要条件是m=2,4,p^{n},2p^{n},其中p为奇质数,n为任意正整数

定理:素数必有原根,如果一个数n有原根那么他有φ(φ(n))个模n不同余的原根

求模素数p的原根的方法:对p-1素因子分解,即p-1=p1^{a1}p2^{a2}...pk^{ak}的标准分解式,若有a^{frac{p-1}{pi}}
eq 1 mod(p)成立,

则a就是p的原根。(对于合数求原根,除了需要预先判断是否存在原根之外,还需要把p-1换成φ(p))

求素数的最小原根程序

const int maxn=100000;
int prime[maxn];
void Get_Prime(){
    memset(prime,0,sizeof(prime));
    for(int i=2;i<=maxn;i++){
        if(!prime[i]) prime[++prime[0]]=i;
        for(int j=1;j<=prime[0]&&prime[j]<=maxn/i;j++){
            prime[prime[j]*i]=1;
            if(i%prime[j]==0) break;
        }
    }
    //for(int i=1;i<=20;i++) cout<<prime[i]<<endl;
}
long long factor[100][2];
int fatCnt;
int GetFactors(long long x){
    fatCnt=0;
    long long tmp=x;
    for(int i=1;prime[i]<=tmp/prime[i];i++){
        factor[fatCnt][1]=0;
        if(tmp%prime[i]==0){
            factor[fatCnt][0]=prime[i];
            while(tmp%prime[i]==0){
                factor[fatCnt][1]++;
                tmp/=prime[i];
            }
            fatCnt++;
        }
    }
    if(tmp!=1){
        factor[fatCnt][0]=tmp;
        factor[fatCnt++][1]=1;
    }
    //for(int i=0;i<fatCnt;i++) cout<<"yinzi="<<factor[i][0]<<"  mi="<<factor[i][1]<<endl;
    return fatCnt;
}
template<class T> T fast_mod(T a,T b,T Mod){
    a%=mod;
    if(b==0) return 1;
    T ans=1,base=a;
    while(b!=0){
        if(b&1)ans=(ans*base)%Mod;
        base=(base*base)%Mod;
        b>>=1;
    }
    return ans;
}
//判断一个数是否有原根
bool judge(int n){
    if(n==2||n==4) return true;
    GetFactors(n);
    if(fatCnt==1) return true;
    if(fatCnt==2&&factor[0][0]==2&&factor[0][1]==1) return true;
    return false;
}
//返回最小的原根,如果没有则返回-1
int Solve(int P){
    if(P==2) return 1;
    //if(!judge(P)) return false;
    GetFactors(P-1);
    for(int g=2;g<P;g++){
        bool flag=true;
        for(int i=0;i<fatCnt;i++){
            int t=(P-1)/factor[i][0];
            if(fast_mod(g,t,P)==1) {
                flag=false;break;
            }
        }
        if(flag) return g;
    }
}
原文地址:https://www.cnblogs.com/033000-/p/10075754.html