首先介绍一下阶的概念:
设a,p是整数,a和p互素,那么使 a的n次方对p取模等于1 成立的最小正整数n叫做a模p的阶.
原根:设m是正整数,a是整数,若a模m的阶等于φ( m),则称a为模m的一个原根。
即:a的φ( m)次方对m取模等于1;
推论:如果p有原根,则它恰有φ( φ( p))个不同的原根,p为素数,当然φ( p)=p-1,因此就有φ( p-1)个原根
代码:
#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;
}
}
}