參照篇原根博客:https://blog.csdn.net/fuyukai/article/details/50894609
1.原根定義
(1)假設一個數g對於P來說是原根,那么g^i mod P的結果兩兩不同,且有 1<g<P, 1<i<P,那么g可以稱為是P的一個原根
簡單來說,g^i mod p ≠ g^j mod p (p為素數)
(2)如果從歐拉函數的角度定義,我們可以先引進一個概念:
階
關於階可以看這里:
https://blog.csdn.net/a27038/article/details/77203892
此時給原根下定義:
此時給原根下定義:
如果
a 與 n 是互質的整數且n>0,那么當 ordna=φ(n)時,稱aa為模n的原根。
有個結論:如果g是P的原根,就是g^(P-1) = 1 (mod P)當且僅當指數為P-1的時候成立.(這里P是素數).
2.如何求解:
一、枚舉
從2開始枚舉,然后暴力判斷g^(P-1) = 1 (mod P)是否當且當指數為P-1的時候成立
而由於原根一般都不大,所以可以暴力得到.
二、講究方法
定理:如果模m有原根,那么他一共有個原根。
定理:如果p為素數,那么素數p一定存在原根,並且模p的原根的個數為個。
定理:假設m是正整數,a是整數,如果a模m的階等於,則稱a為模m的一個原根。
模m有原根的充要條件:m=2,4,P^a,2*P^a…….
求模素數P的原根的方法:對P-1素因子分解,即P-1=(P1^a1)(P2^a2)…..(Pk^ak)。,若恆有成立,那么g就是P的原根(對於合數而言,只需要把p-1換成
即可)
求解一個數最小原根代碼:

1 #include <stdio.h> 2 #include <algorithm> 3 #include <cmath> 4 #include <iostream> 5 #include <string.h> 6 #include <cstring> 7 using namespace std; 8 const int MAX_N = 1000010; 9 typedef long long ll; 10 11 int prime_cnt, factor_cnt, p; 12 int vis[MAX_N], prime[MAX_N], factor[MAX_N]; 13 14 void GetPrime() 15 { 16 prime_cnt = 0; 17 memset(vis, 0, sizeof(vis)); 18 for(int i = 2; i < MAX_N; i++){ 19 if(!vis[i]){ 20 prime[prime_cnt++] = i; 21 for(int j = 0; j < prime_cnt && prime[j] * i < MAX_N; j++){ 22 vis[i * prime[j]] = 1; 23 if(i % prime[j] == 0) break; 24 } 25 } 26 } 27 } 28 29 void Factor(int x) 30 { 31 factor_cnt = 0; 32 int t = (int) sqrt(x + 0.5); 33 for(int i = 0; prime[i] <= t; i++){ 34 if(x % prime[i] == 0){ 35 factor[factor_cnt++] = prime[i]; 36 while(x % prime[i] == 0) x /= prime[i]; 37 } 38 } 39 if(x > 1) factor[factor_cnt++] = x; 40 } 41 42 ll quick_pow(ll n, ll m, ll mod) 43 { 44 ll res = 1, tmp = n % mod; 45 while(m){ 46 if(m & 1) res = res * tmp % mod; 47 tmp = tmp * tmp % mod; 48 m >>= 1; 49 } 50 return res; 51 } 52 53 void solve() 54 { 55 Factor(p - 1); 56 for(int g = 2; g < p; g++){ 57 bool flag = true; 58 for(int i = 0; i < factor_cnt; i++){ 59 int t = (p - 1) / factor[i]; 60 if(quick_pow((ll)g, (ll)t, (ll)p) == 1){ 61 flag = false; 62 break; 63 } 64 } 65 if(flag){ 66 cout << g << endl; 67 break; 68 } 69 } 70 } 71 72 int main() 73 { 74 GetPrime(); 75 while(cin >> p){ 76 solve(); 77 } 78 return 0; 79 }