原根

来源:互联网 发布:iis php mysql 配置 编辑:程序博客网 时间:2024/06/10 01:32


定义:,使得成立的最小的,称为对模的阶,记为


定理:如果模有原根,那么它一共有个原根。


定理:,则


定理:如果为素数,那么素数一定存在原根,并且模的原根的个数为


定理:是正整数,是整数,若的阶等于,则称为模的一个原根。


   假设一个数对于模来说是原根,那么的结果两两不同,且有,那么可以称为是模的一个原根,归根到底就是当且仅当指数为的时候成立。(这里是素数)


有原根的充要条件:,其中是奇素数。

 


求模素数原根的方法:素因子分解,即的标准分解式,若恒有


          


成立,就是的原根。(对于合数求原根,只需把换成即可)

/*********************求一个数的原根(一)p是一个质数p-1 = p1^a1*p1*a2*...*pk^ak;对于所有的pi都有g^((p-1)/pi)!=1(mod p);那么g是模p的一个原根(二) p是一个合数将p-1改成phi(p)就行了。**********************/#include <iostream>#include <cstdio>#include <cstring>using namespace std;const int maxn = 50010;typedef long long LL;int p[maxn],cnt;void divide(int n){    cnt=0;    for(int i=2;i*i<=n;i++){        if(n%i==0){            p[cnt++]=i;            while(n%i==0) n/=i;        }    }    if(n>1) p[cnt++]=n;}LL quick_mod(LL a,LL b,LL m){    LL ans = 1;    a%=m;    while(b){        if(b&1){            ans = ans*a%m;            b--;        }        b>>=1;        a=a*a%m;    }    return ans;}int main(){    int n;    while(~scanf("%lld",&n)){        divide(n-1);        for(int i=2;i<n;i++){            bool tag = 0;            for(int j=0;j<cnt;j++){                if(quick_mod(i,(n-1)/p[j],n)==1){                    tag = 1;                    break;                }            }            if(!tag){                printf("%d\n",i);                break;            }        }    }    return 0;}

0 0