zoukankan      html  css  js  c++  java
  • 求素数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;
        }
    }
  • 相关阅读:
    多线程爬取图片(生产者-消费者模式)
    数据结构1_C---单链表的逆转
    Java基础面试知识点总结
    Java工程师必备书单
    Java工程师修炼之路(校招总结)
    Java秋招面经大合集
    我的秋招经验分享(已拿BAT头条网易滴滴)
    听说go语言越来越火了?那么请收下这一份go语言书单吧!
    2020还是AI最火?推荐几本深度学习的书籍帮你入门!
    人工智能真的有那么神秘么,推荐一份机器学习入门书单搞定它!
  • 原文地址:https://www.cnblogs.com/033000-/p/10075754.html
Copyright © 2011-2022 走看看