51nod 1135 求原根

51nod 1135 求原根

传送门

先把AC代码写了,有空再填坑。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+5;
#define mst(a) memset(a,0,sizeof a)
#define lx x<<1
#define rx x<<1|1
#define reg register
ll ksm(ll a,ll n,ll p){  //快速幂 
	ll ans=1;
	while(n){
		if(n&1) ans=ans*a%p;
		a=a*a%p;
		n>>=1;
	}
	return ans;
}
int p[N],cnt,jg[N],P,tot,num[N];
void ss(){		//欧拉筛. 
	int n=1e5;
	jg[1]=jg[0]=1;
	for(int i=2;i<=n;i++){
		if(!jg[i]) p[++cnt]=i;
		for(int j=1;j<=cnt&&p[j]*i<=n;j++){
			jg[i*p[j]]=1;
			if(i%p[j]==0) break;
		}
	}
}
void fun(){	//预处理 对P-1进行素数分解. 
	int x=P-1;
	 for(int i=1;1LL*p[i]*p[i]<=x;i++){
	 		if(x%p[i]==0){
	 			 num[++tot]=p[i];
	 			 while(x%p[i]==0) x/=p[i];
			}
	 }
	 if(x!=1) num[++tot]=x;
}
bool check(int x){	 //定理. 
	 for(int i=1;i<=tot;i++)
	 	if(ksm(x,(P-1)/num[i],P)==1) return 0;
	 return 1;
} 
int main(){
	ss();
	 scanf("%d",&P);
	fun();
	 for(reg int i=2;i<P;i++)
	 	if(check(i)) printf("%d\n",i),exit(0);
}

猜你喜欢

转载自blog.csdn.net/weixin_45750972/article/details/106606075