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编辑  收藏  举报