poj 2478 Farey Sequence(基于素数筛法求欧拉函数)

http://poj.org/problem?id=2478

求欧拉函数的模板。

初涉欧拉函数,先学一学它基本的性质。

1.欧拉函数是求小于n且和n互质(包括1)的正整数的个数。记为φ(n)。

2.欧拉定理:若a与n互质,那么有a^φ(n) ≡ 1(mod n),经常用于求幂的模。

3.若p是一个质数,那么φ(p) = p-1,注意φ(1) = 1。

4.欧拉函数是积性函数:

若m与n互质,那么φ(nm) = φ(n) * φ(m)。

若n = p^k且p为质数,那么φ(n) = p^k - p^(k-1) = p^(k-1) * (p-1)。

5.当n为奇数时,有φ(2*n) = φ(n)。

6.基于素数筛的求欧拉函数的重要依据:

设a是n的质因数,若(N%a == 0 && (N/a)%a == 0) 则 φ(N) = φ(N/a)*a; 若(N%a == 0 && (N/a)%a != 0) 则φ(N) = φ(N/a)*(a-1)。

该题就是基于性质六,在线性时间内求欧拉函数。

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

using namespace std;
const int maxn = 1000010;
const int INF = 0x3f3f3f3f;

int n;
LL num[maxn];

LL phi[maxn]; //对应φ(i)
int flag[maxn]; //flag[i] = 0说明i是素数,否则不是素数
int prime[maxn];//存素数

void get_phi()
{
	int i,j,k;
	memset(flag,0,sizeof(flag));
	phi[1] = 1;
	k = 0;

	for(i = 2; i <= maxn; i++)
	{
		if(!flag[i]) //i是素数
		{
			phi[i] = i-1;
			prime[++k] = i;
		}
		for(j = 1; j <= k && prime[j]*i <= maxn; j++)
		{
			flag[i*prime[j]] = 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 main()
{
	get_phi();
	num[1] = 0;
	for(int i = 2; i <= maxn; i++)
		num[i] = num[i-1] + phi[i];

	while(~scanf("%d",&n)&&n)
		printf("%lld\n",num[n]);

	return 0;
}

poj 2478 Farey Sequence(基于素数筛法求欧拉函数),布布扣,bubuko.com

时间: 2024-12-10 03:06:09

poj 2478 Farey Sequence(基于素数筛法求欧拉函数)的相关文章

【poj2478-Farey Sequence】递推求欧拉函数-欧拉函数的几个性质和推论

http://poj.org/problem?id=2478 题意:给定一个数x,求<=x的数的欧拉函数值的和.(x<=10^6) 题解:数据范围比较大,像poj1248一样的做法是不可行的了. 首先我们要了解欧拉函数的几个性质和推论:(今天跟好基友Konjak魔芋讨论了好久..) 推论(一): phi(p^k)=(p-1)*p^(k-1) 证明: 令n=p^k,小于等于n的正整数数中,所有p的倍数共有p^k /p = p^(k-1)个. 1~n出去p的倍数,所以phi(n)= n -  p^

O(n)求素数,求欧拉函数,求莫比乌斯函数,求对mod的逆元,各种求

筛素数 void shai() { no[1]=true;no[0]=true; for(int i=2;i<=r;i++) { if(!no[i]) p[++p[0]]=i; int j=1,t=i*p[1]; while(j<=p[0] && t<=r) { no[t]=true; if(i%p[j]==0) //每一个数字都有最小质因子.这里往后的数都会被筛过的,break break; t=i*p[++j]; } } } O(n)筛欧拉函数 void find()

筛法求欧拉函数(poj2478

求1-n的欧拉函数的值 #include <iostream> #include <cstdio> #include <queue> #include <algorithm> #include <cmath> #include <cstring> #define inf 2147483647 #define N 1000010 #define p(a) putchar(a) #define For(i,a,b) for(long lo

BZOJ 2818: Gcd区间内最大公约数 为素数的对数(欧拉函数的应用)

传送门 2818: Gcd Time Limit: 10 Sec Memory Limit: 256 MB Submit: 3649 Solved: 1605 [Submit][Status][Discuss] Description 给定整数N,求1<=x,y<=N且Gcd(x,y)为素数的 数对(x,y)有多少对. Input 一个整数N Output 如题 Sample Input 4 Sample Output 4 HINT hint 对于样例(2,2),(2,4),(3,3),(4,

POJ 2478 Farey Sequence 筛选法求欧拉函数

题目来源:POJ 2478 Farey Sequence 题意:输入n 求 phi(2)+phi(3)+phi(4)+...+phi(n) 思路:用类似筛法的方式计算phi(1), phi(2), ..., phi(n) 再求前缀和 #include <cstdio> #include <cstring> #include <cmath> //欧拉phi函数 const int maxn = 1000010; typedef long long LL; int eule

POJ 2478 Farey Sequence

Description The Farey Sequence Fn for any integer n with n >= 2 is the set of irreducible rational numbers a/b with 0 < a < b <= n and gcd(a,b) = 1 arranged in increasing order. The first few are F2 = {1/2} F3 = {1/3, 1/2, 2/3} F4 = {1/4, 1/3,

POJ 2478 Farey Sequence( 欧拉函数 + 法雷数列 )

POJ 2478 Farey Sequence ( 欧拉函数 + 法雷数列 ) #include <cstdio> #include <cstring> using namespace std; #define MAXN 1000005 typedef long long LL; int vis[ MAXN ], prime[ MAXN ], cnt, n; LL phi[ MAXN ]; void get_phi_prime( int N ) { phi[1] = 1; cnt

POJ - 2478 Farey Sequence(phi打表)

题目: Description The Farey Sequence Fn for any integer n with n >= 2 is the set of irreducible rational numbers a/b with 0 < a < b <= n and gcd(a,b) = 1 arranged in increasing order. The first few are F2 = {1/2} F3 = {1/3, 1/2, 2/3} F4 = {1/4,

POJ 2478 Farey Sequence(欧拉函数前n项和)

题意 求欧拉函数的前n项和 水题 打表筛选即可 #include <iostream> #include <math.h> using namespace std; long long a[1000005]={0}; long long c[1000005]={0}; void enlur() { int i,j; for(i=2;i<1000005;i++) { if(!a[i]) { for(j=i;j<1000005;j=j+i) { if(!a[j]) a[j]