您的位置:首页 > 其它

51nod 1135 求原根(板子

2017-08-07 12:43 155 查看
1135 原根


基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题


 收藏


 关注

设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 <cstdio>
#include <cmath>
#include <cstring>
#include <vector>
#include <algorithm>
using namespace std;
#define LL __int64
#define PB push_back
LL mul(LL a,LL b,LL m)
{
LL ret = 0;
a %= m;
while(b)
{
if(b & 1) ret = (ret + a) % m;
a = (a + a) % m;
b >>= 1;
}
return ret;
}
LL a_b_MOD_c(LL a,LL b,LL m)
{
LL ret = 1;
a %= m;
while(b)
{
if(b&1) ret = mul(ret,a,m);
a = mul(a,a,m);
b >>= 1;
}
return ret;
}

vector<LL> a;
bool g_test(LL g,LL p)
{
for(LL i=0; i<a.size(); ++i)
if(a_b_MOD_c(g,(p-1)/a[i],p)==1)
return 0;
return 1;
}
LL pri_root(LL p)
{
a.clear();
LL tmp=p-1;
for(LL i=2; i<=tmp/i; ++i)
if(tmp%i==0)
{
a.push_back(i);
while(tmp%i==0)
tmp/=i;
}
if(tmp!=1)
a.push_back(tmp);
LL g=1;
while(true)
{
if(g_test(g,p))
return g;
++g;
}
}

int main()
{
LL x;
while(~scanf("%lld",&x))
cout<<pri_root(x)<<endl;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: