您的位置:首页 > 其它

poj 1284 Primitive Roots(原根+欧拉函数)

2014-07-24 18:44 363 查看
http://poj.org/problem?id=1284

原根



题意:对于奇素数p,如果存在一个x(1<x<p),(x^i)%p两两不同(0<i<p),且解集等于{1,2....,p-1}。称x是p的一个原根。输入p问p的原根有多少个。

直接枚举的,TLE了。看到discuss里面说是求原根,答案直接是phi[p-1]。百度百科上直接就给出答案了。m有原根的充要条件是m=
1,2,4,p,2p,p^n,其中p是奇素数,n是任意正整数。它所含原根的个数是phi[phi[m]],因为phi[m]=m-1,所以答案是phi[m-1]。


#include <stdio.h>
#include <iostream>
#include <map>
#include <set>
#include <stack>
#include <vector>
#include <math.h>
#include <string.h>
#include <queue>
#include <string>
#include <stdlib.h>
#include <algorithm>
#define LL long long
#define _LL __int64
#define eps 1e-12
#define PI acos(-1.0)
using namespace std;

const int maxn = 65540;
int flag[maxn];
int prime[maxn];
int phi[maxn];

void init()
{
	memset(flag,0,sizeof(flag));
	phi[1] = 1;
	prime[0] = 0;
	for(int i = 2; i < maxn; i++)
	{
		if(flag[i] == 0)
		{
			phi[i] = i-1;
			prime[++prime[0]] = i;
		}
		for(int j = 1; j <= prime[0]&&prime[j]*i<maxn; j++)
		{
			flag[prime[j]*i] = 1;
			if(i%prime[j] == 0)
				phi[i*prime[j]] = phi[i] * prime[j];
			else
				phi[i*prime[j]] = phi[i] * (prime[j]-1);
		}
	}
}
int p;
int main()
{
	init();
	while(scanf("%d",&p) != EOF)
	{
		printf("%d\n",phi[p-1]);
	}
	return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: