51nod-1135 原根

44 篇文章 0 订阅
基准时间限制: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


Code :

/*
设 m 是正整数,a是整数,若a模m的阶等于φ(m),则称 a 为 模m的一个原根。(其中φ(m)表示m的欧拉函数)
阶:gcd(a,m)=1,使得 a^r%m=1 成立的最小的 r,称为 a 对 模m 的 阶。
φ(m):在[1,m)的区间内与m互质的数的个数。

求模素数p的原根a的方法:
因为p为素数,所以φ(p)=p-1, 这题就是要找最小的a使得 a^(p-1)%p = 1 成立(根据费马小定理,该式一定成立),
先求p-1所有不同的 质因子 p1,p2…pm,
对任何整数 a ∈[1,p-1], 检验 a 是否为 p 的原根,
检验方法:a^((p-1)/p1),a^((p-1)/p2),...a^((p-1)/pm) 中是否存在一个 模p 等于 1 ,
存在的话 a 就不是 模p 的一个原根(即p-1就不是a对模p的阶),否则a就为原根。

 欧拉函数 Euler函数表达通式:euler(x)=x(1-1/p1)(1-1/p2)(1-1/p3)(1-1/p4)…(1-1/pn),
其中p1,p2……pn为x的所有素因数,x是不为0的整数。euler(1)=1(唯一和1互质的数就是1本身)。
 ***素数m的欧拉函数 φ(m)=m-1
(a,m)=1; m>=1
a^x % m=1 且 x =  φ(m) --m的欧拉函数 
a^ φ(m) %m=1  ->  a为模m的一个原根 
*/ 
#include<iostream>
#include<vector>
using namespace std;
typedef long long LL;

int n;
LL ans;
vector<int> ive;

void get_Prime(int x);
LL get_pow(LL a,LL b,int mod); 
int main()
{
	ios::sync_with_stdio(false);
	cin>>n;
	get_Prime(n-1);
	for(int i=2;i<n;++i)
	{
		bool boo=true;
		for(auto t:ive) 
			if(get_pow(i,(n-1)/t,n)==1){
				boo=false;	break;
			}
		if(boo==true){
			ans=i;	break;
		}
	}
	cout<<ans<<endl;
	return 0;
}

void get_Prime(int x)//线性筛选素数  NUM 素数个数
{ 
	for(int i=2; i*i<=x; i++)
		if(x%i==0){
			ive.push_back(i);
			while(x%i==0){
				x/=i;
			}
		}
    if(x>1)	ive.push_back(x);
}

LL get_pow(LL a,LL b,int mod)//快速幂取余
{
    LL res=1;
    while(b>0){
        if(b&1)	res=res*a%mod;
        b=b>>1;
        a=a*a%mod;
    }
    return res;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值