51nod 1135 原根

#传送门

描述

设m是正整数,a是整数,若a模m的阶等于φ(m),则称a为模m的一个原根。(其中φ(m)表示m的欧拉函数)
给出1个质数P,找出P最小的原根。

输入

输入1个质数P(3 <= P <= 10^9)

输出

输出P最小的原根。

输入样例

3

输出样例

2

对于原根,有个阶的性质,就是 a k ≡ 1 ( m o d   p ) a^k\equiv 1(mod~p) ak1(mod p)这时称k为关于a模p的阶。
然后原根也有一些性质,具体性质就不多说了,看wiki上的吧或者自行百度

附上AC代码:
#include<bits/stdc++.h>
#define debug() cout<<"========"<<endl;
using namespace std;
typedef long long ll;
const int MANX=1e5;
int mum[MANX],cnt;
bool dis[MANX];
inline int phi(int x) {
	int ans=x;
	for(int i=2; i*i<=x; i++) {
		if(x%i==0) {
			ans = ans/i*(i-1);
			while(x%i==0)x/=i;
		}
	}
	if(x>1)ans=ans/x*(x-1);
	return ans;
}
inline int quick(int a,int b,int p) {
	ll ans=1;
	while(b) {
		if(b&1)ans=1ll*ans*a%p;
		a=1ll*a*a%p;
		b>>=1;
	}
	return ans;
}
inline int check(int x) {
	int t=phi(x);
	int q=sqrt(t),tt=t;
	for(int i=2; i<=q; i++) {
		if(t%i==0) {
			mum[cnt++]=t/i;
		}
		while(x%i==0)t/=i;
	}
	if(t>1)mum[cnt++]=tt/t;
	for(int g=2;; g++) {
		bool find=true;
		if(quick(g,tt,x)==1) {
			for(int i=0; i<cnt; i++) {
				if(quick(g,mum[i],x)==1) {
					find=false;
					break;
				}
			}
			if(find) {
				cout<<g<<endl;
				break;
			}
		}
	}
}
int main() {
	int p;
	cin>>p;
	check(p);
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值