POJ 2478 Farey Sequence

/*
POJ 2478 Farey Sequence
http://poj.org/problem?id=2478
欧拉函数 线性筛
原问题转化成1-n之间的欧拉函数和,因此利用线性筛在O(n)时间内求出其欧拉函数值
在求前缀和即可。
 *
 *
 *
 */
#include <cstdio>
#include <algorithm>
using namespace std;
const int Nmax=1000005;
long long num[Nmax];
long long prime[Nmax];
long long phi[Nmax];
int is_prime[Nmax];
int prime_cnt;
int n;
/*long long oula(long long n)*/
//{
    //long long ret=1LL,i;
    //for(i=2;i*i<=n;i++)
    //{
        //if(n%i==0)
        //{
            //n/=i,ret*=i-1LL;
            //while(n%i==0LL) n/=i,ret*=i;
        //}
    //}
    //if(n>1LL) ret*=n-1LL;
    //return ret;
/*}*/

void get()
{
    for(int i=2;i<Nmax;i++)
        is_prime[i]=1;
    for(long long i=2;i<Nmax;i++)
    {
        if(is_prime[i])
        {
            prime[++prime_cnt]=i;
            phi[i]=i-1;
        }
        for(int j=1;j<=prime_cnt;j++)
        {
            if(i*prime[j]>=Nmax)
                break;
            is_prime[i*prime[j]]=0;
            if(i%prime[j]==0)
            {
                phi[i*prime[j]]=phi[i]*prime[j];
                break;
            }
            else
                phi[i*prime[j]]=phi[i]*(prime[j]-1);
        }
    }
}


int main()
{
    //freopen("a.in","r",stdin);
    get();
    for(int i=2;i<Nmax;i++)
        phi[i]+=phi[i-1];
    int n;
    while(scanf("%d",&n)==1)
    {
        if(!n)
            break;
        printf("%lld\n",phi[n]);
    }
    return 0;
}

 

posted @ 2017-03-09 17:16  BBBob  阅读(134)  评论(0编辑  收藏  举报