# poj2478——Farey Sequence（欧拉函数）

Farey Sequence
 Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 18507 Accepted: 7429

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, 1/2, 2/3, 3/4}
F5 = {1/5, 1/4, 1/3, 2/5, 1/2, 3/5, 2/3, 3/4, 4/5}

You task is to calculate the number of terms in the Farey sequence Fn.

Input

There are several test cases. Each test case has only one line, which contains a positive integer n (2 <= n <= 106). There are no blank lines between cases. A line with a single 0 terminates the input.

Output

For each test case, you should output one line, which contains N(n) ---- the number of terms in the Farey sequence Fn.

Sample Input

2
3
4
5
0

Sample Output

1
3
5
9题意：给出一个数n，要你求出在1-n中，互质的数有多少对；思路：这题属于欧拉函数的应用。1-n中互质数的对数就是等于与2互质的数的个数+与3互质的数的个数+与4互质的数的个数+....+与n互质的数的个数。（为什么没有1，因为一个数无法成对）所以这题就演变成了求2-n中所有数的欧拉函数的和，所以要用到欧拉函数的变形写法。因为是多组输入，所以要预处理一下，提前记录下n为1-1000000时的值。代码：
 1 #include<iostream>
2 #include<cstring>
3 #include<cstdio>
4 #include<string>
5 #include<cmath>
6 #include<algorithm>
7 #include<stack>
8 #include<queue>
9 #define eps 1e-7
10 #define ll long long
11 #define inf 0x3f3f3f3f
12 #define pi 3.141592653589793238462643383279
13 using namespace std;
14 ll n,euler[1000006],sum[1000006];
15 int main()
16 {
17     for(int i=1; i<=1000000; ++i) //初始化所有数的欧拉函数值为自己
18         euler[i] = i;
19     for(int i=2; i<=1000000; ++i) //求所有数的欧拉函数值
20     {
21         if(euler[i] == i) //根据公式 欧拉值（n） = n*（1-1/p1）（1-1/p2）...（1-1/pi）其中p为n的素因子
22         //可知素数只有自己是自己的素因子，所以在遇到自己以前euler值没变，所以可以通过上面的语句得知euler[i]==i的为素数
23         {
24             for(int j=i; j<=1000000; j+=i) //所有i的倍数乘上（1-1/i）
25                 euler[j] = euler[j]/i*(i-1);
26         }
27     }
28     sum[1] = 0;
29     for(int i=2; i<=1000000; ++i) //提前记录下每个数的答案
30     {
31         sum[i] = sum[i-1] + euler[i];
32     }
33     while(scanf("%lld",&n)!=EOF)
34     {
35         if(!n) break;
36         printf("%lld\n",sum[n]);
37     }
38     return 0;
39 }

posted @ 2018-07-17 11:17  特务依昂  阅读(333)  评论(0编辑  收藏  举报