#传送门
描述
设m是正整数,a是整数,若a模m的阶等于φ(m),则称a为模m的一个原根。(其中φ(m)表示m的欧拉函数)
给出1个质数P,找出P最小的原根。
输入
输入1个质数P(3 <= P <= 10^9)
输出
输出P最小的原根。
输入样例
3
输出样例
2
对于原根,有个阶的性质,就是
a
k
≡
1
(
m
o
d
p
)
a^k\equiv 1(mod~p)
ak≡1(mod p)这时称k为关于a模p的阶。
然后原根也有一些性质,具体性质就不多说了,看wiki上的吧或者自行百度
附上AC代码:
#include<bits/stdc++.h>
#define debug() cout<<"========"<<endl;
using namespace std;
typedef long long ll;
const int MANX=1e5;
int mum[MANX],cnt;
bool dis[MANX];
inline int phi(int x) {
int ans=x;
for(int i=2; i*i<=x; i++) {
if(x%i==0) {
ans = ans/i*(i-1);
while(x%i==0)x/=i;
}
}
if(x>1)ans=ans/x*(x-1);
return ans;
}
inline int quick(int a,int b,int p) {
ll ans=1;
while(b) {
if(b&1)ans=1ll*ans*a%p;
a=1ll*a*a%p;
b>>=1;
}
return ans;
}
inline int check(int x) {
int t=phi(x);
int q=sqrt(t),tt=t;
for(int i=2; i<=q; i++) {
if(t%i==0) {
mum[cnt++]=t/i;
}
while(x%i==0)t/=i;
}
if(t>1)mum[cnt++]=tt/t;
for(int g=2;; g++) {
bool find=true;
if(quick(g,tt,x)==1) {
for(int i=0; i<cnt; i++) {
if(quick(g,mum[i],x)==1) {
find=false;
break;
}
}
if(find) {
cout<<g<<endl;
break;
}
}
}
}
int main() {
int p;
cin>>p;
check(p);
return 0;
}