首页 > 代码库 > hdu4992 Primitive Roots(所有原根)

hdu4992 Primitive Roots(所有原根)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4992

题意:给出n,输出n的所有原根。

思路:求出n的一个原根x,那么对于所以的i,i<phi(n)且(i,phi(n))=1,x^i%n都是n的原根。

 

int Euler(int n){    int i,ans=n;    for(i=2;i*i<=n;i++) if(n%i==0)    {        ans=ans/i*(i-1);        while(n%i==0) n/=i;    }    if(n>1) ans=ans/n*(n-1);    return ans;}int prime[N],tag[N],cnt;void init(){	int i,j;	for(i=2;i<N;i++) if(!tag[i])	{		prime[cnt++]=i;		for(j=i+i;j<N;j+=i) tag[j]=1;	}	tag[1]=1;}int get(int x){	if(x%2==0) return 0;	int i;	for(i=0;i<cnt&&prime[i]*prime[i]<=x;i++) if(x%prime[i]==0)	{		while(x%prime[i]==0) x/=prime[i];		if(x!=1) return 0;		return prime[i];	}	return x;}int n;int myPow(i64 x,i64 y){	i64 ans=1;	while(y)	{		if(y&1) ans=ans*x%n;		x=x*x%n;		y>>=1;	}	return (int)ans;}int ee;vector<int> V;int ok(int t){	if(myPow(t,ee)!=1) return 0;	int i;	FOR0(i,SZ(V)) if(myPow(t,V[i])==1) return 0;	return 1;}int Gcd(int x,int y){	if(y==0) return x;	return Gcd(y,x%y);}int main(){	init();	while(scanf("%d",&n)!=-1)	{		if(n==2)		{			puts("1");			continue;		}		if(n==4)		{			puts("3");			continue;		}		int t=n%2==0?get(n/2):get(n);		if(!t)		{			puts("-1");			continue;		}		ee=Euler(n);		V.clear();		int i;		for(i=2;i*i<=ee;i++) if(ee%i==0)		{			V.pb(i);			if(i*i!=ee) V.pb(ee/i);		}		for(i=2;i<n;i++) if(ok(i)) break;		int Min=i;		vector<int> ans;		for(i=1;i<ee;i++) 		{			if(Gcd(i,ee)!=1) continue;			ans.pb(myPow(Min,i));		}		sort(all(ans));		for(i=0;i<SZ(ans);i++)		{			if(i) putchar(‘ ‘);			printf("%d",ans[i]);		}		puts("");	}}

 

hdu4992 Primitive Roots(所有原根)