题目链接:
51nod 1135 原根
题意:
求素数p的最小原根。
#include <stdio.h>
#include <algorithm>
#include <cmath>
#include <iostream>
#include <string.h>
#include <cstring>
using namespace std;
const int MAX_N = 1000010;
typedef long long ll;
int prime_cnt, factor_cnt, p;
int vis[MAX_N], prime[MAX_N], factor[MAX_N];
void GetPrime()
{
prime_cnt = 0;
memset(vis, 0, sizeof(vis));
for(int i = 2; i < MAX_N; i++){
if(!vis[i]){
prime[prime_cnt++] = i;
for(int j = 0; j < prime_cnt && prime[j] * i < MAX_N; j++){
vis[i * prime[j]] = 1;
if(i % prime[j] == 0) break;
}
}
}
}
void Factor(int x)
{
factor_cnt = 0;
int t = (int) sqrt(x + 0.5);
for(int i = 0; prime[i] <= t; i++){
if(x % prime[i] == 0){
factor[factor_cnt++] = prime[i];
while(x % prime[i] == 0) x /= prime[i];
}
}
if(x > 1) factor[factor_cnt++] = x;
}
ll quick_pow(ll n, ll m, ll mod)
{
ll res = 1, tmp = n % mod;
while(m){
if(m & 1) res = res * tmp % mod;
tmp = tmp * tmp % mod;
m >>= 1;
}
return res;
}
void solve()
{
Factor(p - 1);
for(int g = 2; g < p; g++){
bool flag = true;
for(int i = 0; i < factor_cnt; i++){
int t = (p - 1) / factor[i];
if(quick_pow((ll)g, (ll)t, (ll)p) == 1){
flag = false;
break;
}
}
if(flag){
cout << g << endl;
break;
}
}
}
int main()
{
GetPrime();
while(cin >> p){
solve();
}
return 0;
}