POJ 2478 Farey Sequence

来源:互联网 发布:结束单身 知乎 编辑:程序博客网 时间:2024/06/09 05:37
Farey Sequence
Time Limit: 1000MS Memory Limit: 65536KTotal Submissions: 15215 Accepted: 6038

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

23450

Sample Output

1359

分析:就是找出小于n且与n互质的数有多少,自然想到欧拉函数,然后dp一下,将前面的累加就行了,但是普通的欧拉函数模板会超时,可以改良一下。

代码:

#include<iostream>#include<cstdio>#include<cstring>#include<cmath>using namespace std;long long p[1000005];//超时//int euler_phi(int n)//{//int m = (int)sqrt(n + 0.5);//int ans = n;//for (int i = 2; i <= m; 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;//}void euler(){for (long long i = 2; i <= 1000000; i++)p[i] = i;for (long long i = 2; i <= 1000000; i++)if (i == p[i])for (long long j = i; j <= 1000000; j += i)p[j] = (p[j] / i)*(i - 1);}int main(){euler();for (int i = 3; i <= 1000000; ++i)p[i] += p[i - 1];int n;while (scanf("%d", &n) && n)printf("%lld\n", p[n]);return 0;}

0 0