模板
求质数P的最小原根
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5+10;
typedef long long ll;
int prime[maxn];
void getPrime() {
memset(prime,0,sizeof(prime));
for(int i=2;i<maxn;i++) {
if(!prime[i]) prime[++prime[0]] = i;
for(int j=1;j<=prime[0]&&prime[j]*i<maxn;j++) {
prime[prime[j]*i] = 1;
if(i%prime[j]==0) break;
}
}
}
ll factor[100][2];
int getFactors(ll x) {
int fatCnt = 0;
ll tmp = x;
for(int i=1;prime[i]<=tmp/prime[i];i++) {
factor[fatCnt][1] = 0;
if(tmp%prime[i]==0) {
factor[fatCnt][0] = prime[i];
while(tmp%prime[i]==0) {
factor[fatCnt][1]++;
tmp/=prime[i];
}
fatCnt++;
}
}
if(tmp!=1) {
factor[fatCnt][0] = tmp;
factor[fatCnt++][1] = 1;
}
return fatCnt;
}
ll power(ll a,ll b,ll m) {
ll res = 1;
ll tmp = a % m;
while(b) {
if(b & 1) res = res * tmp % m;
tmp = tmp * tmp % m;
b >>= 1;
}
return res;
}
ll solve(ll P) {
if(P == 2) {
return 1;
}
int fatCnt = getFactors(P-1);
for(int g=2;g<P;g++) {
bool flag = true;
for(int i=0;i<fatCnt;i++) {
ll t = (P - 1) / factor[i][0];
if(power(g,t,P) == 1) {
flag = false;
break;
}
}
if(flag) return g;
}
}
int main()
{
getPrime();
ll p;
while(~scanf("%lld",&p)) {
printf("%lld\n",solve(p));
}
return 0;
}