首页 > 代码库 > math2478

math2478

 

 

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.

 

Each test case has only one line, which contains a positive integer n (2 <= n <= 106).

 

这里依然是求欧拉函数,但是f(5)表示不仅仅是5的欧拉函数,还要包括之前所有1-4的所有欧拉函数之和。

 

本题的关键是由于n太大,如果直接按照3090的方法对于n,从根号n里面一个个地尝试,然后确定因数的话,则会超时。这里依然用了筛选法的思想。

 

 

#include <stdio.h>

#include <stdlib.h>

 

#define N 1000000

 

//poj2478

 

static char prime[N + 1];

static __int64 ans[N + 1];

 

int main()

{

    int i, j, n;

 

    prime[0] = prime[1] = 0;

    for (i=2; i<=N; i++)

        prime[i] = 1;

 

//原始筛选法求出所有质数

    for (i=2; i*i<=N; i++)

    {

        if (prime[i])

        {

            for (j=i*i; j<=N; j+=i)

                prime[j] = 0;

        }

    }

 

    for (i=1; i<=N; i++)

        ans[i] = i;

 

 

///由于所有合数最终都会被质数分解,因此对于大小为i的质数,数i,2*i,3*i....n*i一定可以被质数分解。这里不用担心某个数n先被i分解以后,不能再被质数j分解。因为如果有这种情况,说明iN中本来可以被J整除的部分,自己整除了,即说明i,j存在公约数,显然与i,j是质数的条件矛盾。因此i一定i,2i,3i...ni质数分解。

    for (i=2; i<=N; i++)

    {

        if (prime[i])

        {

            for (j=i; j<=N; j+=i)

                ans[j] = ans[j] / i * (i - 1);//欧拉公式,先除后乘,防止越界

        }

    }

    for (i=3; i<=N; i++)

        ans[i] += ans[i - 1];

//对于i,f(i)=f(1)+f(2)+f(3)...f(i-1)。因此把前一个加到后一个即可满足要求

 

//    printf("ok\n");

 

    scanf("%d", &n);

    while (n != 0)

    {

        printf("%I64d\n", ans[n]);

        scanf("%d", &n);

    }

 

    return 0;

}

 

math2478