因为最小原根都不大,可以考虑暴力枚举去验证。
对于一个奇质数 P P P,可以先对 ( P − 1 ) (P-1) (P−1)质因数分解为 ( P − 1 ) = p 1 a 1 p 2 a 2 p 3 a 3 . . . . p t a t (P-1) = p_1^{a_1}p_2^{a_2}p_3^{a_3}....p_t^{a_t} (P−1)=p1a1p2a2p3a3....ptat
对于枚举的数
G
G
G,若恒有
G
(
P
−
1
)
/
p
i
≠
1
(
m
o
d
P
)
G^{(P-1)/p_i} \neq 1(mod\ P)
G(P−1)/pi̸=1(mod P)
则
G
G
G为
P
P
P的原根。
代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int A = 1e4 + 10;
int q[A];
int pow(ll a,int b,int P){
ll t = 1;
while(b){
if(b&1) t = t*a%P;
a = (ll)a*a%P;
b>>=1;
}
return t;
}
int get_G(int n){
int i,j,t=0;
int tem = n-1;
for(int i=2 ;(ll)i*i<=tem ;i++){
if(tem%i == 0){
while(tem%i==0) tem/=i;
q[t++] = i;
}
}
if(tem>1) q[t++] = tem;
for(i=2;;i++){
for(j=0 ;j<t ;j++) if(pow(i,(n-1)/q[j],n) == 1) break;
if(j==t) return i;
}
}
int main(){
int P;scanf("%d",&P);
printf("%d\n",get_G(P));
return 0;
}