poj2478 Farey Sequence (欧拉函数)

来源:互联网 发布:mac如何删除应用 编辑:程序博客网 时间:2024/05/23 00:05

Farey Sequence
Time Limit: 1000MS Memory Limit: 65536KTotal Submissions: 17495 Accepted: 7014

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

Source

POJ Contest,Author:Mathematica@ZSU

题目链接:http://poj.org/problem?id=2478

思路:求出前n个数的欧拉函数和即可

①筛选法求欧拉函数

#include <cstdio>#include <cstring>#include <algorithm>#define LL long longusing namespace std;const int N = 1e6 + 10;int phi[N],n;void init(){    memset(phi,0,sizeof(phi));    for(int i = 2; i < N; i ++){        if(!phi[i]){            for(int j = i; j < N; j += i){                if(!phi[j]) phi[j] = j;                phi[j] = phi[j] / i * (i-1);            }        }    }}int main(){    init();    while(~scanf("%d",&n) && n){        LL sum = 0;        for(int i = 2; i <= n; i ++) sum += phi[i];        printf("%I64d\n",sum);    }    return 0;}

②递推求欧拉函数


#include <cstdio>#include <cstring>#include <algorithm>#define LL long longusing namespace std;const int N = 1e6;int minDiv[1100000],phi[1100000],n;//minDIv[i]表示i的最小质因数void init(){    for(int i = 1; i <= N; i ++) minDiv[i] = i;    for(int i = 2; i * i <= N; i ++){        if(minDiv[i] == i){            for(int j = i + i; j <= N; j += i){                minDiv[j] = i;            }        }    }    phi[1] = 1;    for(int i = 2; i <= N; i ++){        phi[i] = phi[i / minDiv[i]];        if(i / minDiv[i] % minDiv[i] == 0) phi[i] *= minDiv[i];        else phi[i] *= (minDiv[i] - 1);    }}int main(){    init();    while(~scanf("%d",&n) && n){        LL sum = 0;        for(int i = 2; i <= n; i ++) sum += phi[i];        printf("%I64d\n",sum);    }    return 0;}





阅读全文
0 0
原创粉丝点击