设m是正整数,a是整数,若a模m的阶等于φ(m),则称a为模m的一个原根。(其中φ(m)表示m的欧拉函数)
给出1个质数P,找出P最小的原根。
Input
输入1个质数P(3 <= P <= 10^9)
Output
输出P最小的原根。
Input示例
3
Output示例
2
公式:
φ(m)=p1e1p2e2...
φ
(
m
)
=
p
1
e
1
p
2
e
2
.
.
.
若存在g,使得
gφ(m)/pi!=1%m
g
φ
(
m
)
/
p
i
!
=
1
%
m
对于每个i都成立,那么g就是m的原根
#include<iostream>
#include<stdio.h>
#include<math.h>
#define ll long long
using namespace std;
int nprime[50005],ctprim,prime[50005];
void isprime()
{
for(int i=2;i<=50000;i++)
{
if(!nprime[i])
{
prime[++ctprim]=i;
}
for(int j=1;j<=ctprim&&prime[j]*i<=50000;j++)
{
nprime[prime[j]*i]=1;
if(i%prime[j]==0)
break;
}
}
}
ll mod;
ll qpow(ll a,ll b)
{
ll ret=a,ans=1;
while(b)
{
if(b&1)
ans=(ans*ret)%mod;
ret=(ret*ret)%mod;
b>>=1;
}
return ans;
}
ll yz[50005],sum;
int main()
{
isprime();
ll x;
scanf("%lld",&mod);
x=mod-1;
int ct=0;
for(int j=1;j<=ctprim;j++)
{
if(x==1)
break;
int sum=1;
while(x%prime[j]==0)
x/=prime[j],sum*=prime[j],yz[++ct]=sum;
}
ll ans=2;
while(1)
{
int flag=0;
for(int i=1;i<=ct;i++)
{
if(qpow(ans,(mod-1)/yz[i])==1)
{
flag=1;
break;
}
}
if(!flag)
break;
ans++;
}
printf("%lld\n",ans);
return 0;
}