0%

原根模板

此程序求最小原根

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
typedef long long LL;
int P,yg;
int ys[100005],nn;
LL getphi(int n) {
LL phi=n;
for (LL i=2;i*i<=n;i++) {
if (n%i==0) {
phi=phi/i*(i-1);
while (n%i==0) n/=i;
}
}
if (n>1) phi=phi/n*(n-1);
return phi;
}
void getyueshu(int n) {
for (int i=1;i*i<=n;i++)
if (n%i==0) ys[++nn]=i;
if (ys[nn]*ys[nn]==n) nn--;
for (int i=nn;i>0;i--) ys[++nn]=n/ys[i];
}
LL fast_pow(LL B,LL x) {
LL tmp=1;
while (x>0) {
if (x&1) tmp=tmp*B%P;
B=B*B%P;
x>>=1;
}
return tmp;
}
int main() {
cin>>P;
int phi=getphi(P);//若是质数直接phi=P-1
getyueshu(phi);
for (int i=1;i<P;i++) {//1是2的原根
if (fast_pow(i,phi)!=1) continue;
bool flag=true;
for (int j=1;j<nn;j++) {
if (fast_pow(i,ys[j])==1) {
flag=false;
break;
}
}
if (flag) {printf("%d",i);return 0;}
}
puts("-1");
return 0;
}