POJ_2478 Farey Sequence 【欧拉函数+简单递推】

一、题目

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 <= 10 6). 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的数字去组合成Farey序列。关于Farey序列,依题意可知,就是1~N的数字中互素的a,b,其中a<b,就可以凑成一个a/b。然后问有多少个不同的a/b

我们先看2,就一个,看3,发现2有的3肯定有,然后其余的就是与3互质的数与3凑成的a/b。再看4,3有的还是有,然后再加上与4互质的数与4凑成的a/b。依次递推下去。就是欧拉函数的前N项和。用一个数组累加保存下来,就是所有结果了,再用线性筛法去求欧拉函数(可以看我之前的欧拉函数学习笔记),速度绝对够。需要注意的是,结果增长的很快,需要用long long

三、AC代码

  

#include <iostream>
#include <cstring>
using namespace std;
const int MAXN = 1e6+5;
int Phi[MAXN], Prime[MAXN], nPrime;
long long Ans[MAXN];

void Euler()
{
    memset(Phi, 0, sizeof(Phi));
    Phi[1] = 1;
    nPrime = 0;
    for(int i = 2; i < MAXN; i++)
    {
        if(!Phi[i]) //i为素数
        {
            Phi[i] = i - 1;
            Prime[nPrime++] = i;
        }
        for(int j = 0; j < nPrime && (long long)i*Prime[j] < MAXN; j++)
        {
            if(i%Prime[j])
            {

                Phi[ i*Prime[j] ] = Phi[i]*(Prime[j]-1);
            }
            else
            {
                Phi[ i*Prime[j] ] = Phi[i]*Prime[j];
                break;
            }
        }
    }
    return;
}

void solve()
{
    Euler();
    Ans[2] = Phi[2];
    for(int i = 3; i < MAXN; i++)
    {
        Ans[i] = Ans[i-1] + Phi[i];
    }
    return;
}


int main()
{
    int N;
    solve();
    while(cin>>N && N)
    {
        cout << Ans[N] << endl;
    }
    return 0;
}

  

猜你喜欢

转载自www.cnblogs.com/dybala21/p/9747695.html