1135 原根

设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
#include <iostream>
#include <vector>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn=100006;
typedef long long ll;
vector<ll>prime,ans;
int vis[100006];
ll p;
void get_prime()
{
    memset(vis,0,sizeof(vis));
    for(int i=2;i<maxn;i++)
    {
        if(vis[i]) continue;
        prime.push_back(i);
        for(int j=2;j*i<maxn;j++)
            vis[j*i]=1; 
    }
}
void get_zhi_prime(ll x)
{
    ans.clear();
    for(int i=0;i<prime.size() && prime[i]*prime[i]<=x;i++)
    {
        if(!(x%prime[i]))
        {
            ans.push_back(prime[i]);
            while(!(x%prime[i]))x/=prime[i];
        }
    }
    if(x>1) ans.push_back(x);
}
ll quick_pow(ll x,ll n,ll mod)
{
    ll ans=1;
    while(n)
    {
        if(n&1) ans=ans*x%mod;
        n>>=1;
        x=x*x%mod;
    }
    return ans;
}
bool solve(ll x,ll n)
{
    for(int i=0;i<ans.size();i++)
    {
        if(quick_pow(x,(p-1)/ans[i],p)==1) return false;
    }
    return true;
}
int main()
{
    get_prime();
    scanf("%lld",&p);
    get_zhi_prime(p-1);
    for(ll i=2;i<=p-1;i++)
    {
        if(solve(i,p))
        {
            printf("%lld
",i);
            break;
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/shinianhuanniyijuhaojiubujian/p/8892319.html