原根、與原根的應用(更新中)


:設a,p是整數,a和p互素,那么:使
  
成立的最小正整數n叫做a模p的階.
 
 
原根:設m是正整數,a是整數,若a mod m的階等於φ(m),則稱a為模m的一個原根.(其中φ(m)表示m的歐拉函數)
假設一個數g是質數P的原根,那么的結果兩兩不同,且有 1<g<P,0<i<P,歸根到底就是當且僅當指數為P-1的時候成立.
 
有了這個上面性質,就可以容易的求出質數P的原根了.
Step1 將P-1進行質因數分解
Step2 枚舉i,並判斷對於每個i是否都有(可以應用快速冪)
第一個符合條件的i就是P的最小原根
 
對於合數,只要將Step2中的p-1替換成φ(p)即可.
 
這里是代碼
#include <cmath>
#include <cstdio>
#define ll long long
#define maxn 1000010
bool vis[maxn];
ll p,prime[maxn],cnt;
ll fp(ll x,ll a){
    ll ret=1;
    for(x%=p;a;a>>=1,x=x*x%p)
        if(a&1) ret=ret*x%p;
    return ret; 
}
void get_prime(int x){//篩出x以內的素數
    for(int i=2;i<=x;i++){
        if(!vis[i]) prime[++cnt]=i;
        for(int j=1;j<=cnt;j++){
            if(i*prime[j]>x) break;
            vis[i*prime[j]]=1;
            if(i%prime[j]==0) break;
        }
    }
}
bool check(ll x){//檢查x是否是p的原根
    ll t=sqrt(x)+10;
    for(int i=1;prime[i]<=t;i++){
        if((p-1)%prime[i]==0&&fp(x,(p-1)/prime[i])%p==1)
            return 0;
    }
    return 1;
}
int main(){
    scanf("%lld",&p);
    get_prime(maxn);
    for(int i=1;i<=1000000;i++){
        if(check(i)){
            printf("%d\n",i);
            return 0;
        }
    }
}

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM