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("");

	}

}

 

你可能感兴趣的:(root)