POJ 2478

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.

求快速欧拉函数的一道题

自己的要344MS,代码如下:

#include"stdio.h"
#include"string.h"
int s[1000001],prime[78498],size=0;
__int64 phi[1000010];
void getprime()
{
	int i;
	memset(s,0,sizeof(s));
	for(i=2;i<=1000000;i++){
		if(!s[i])
			prime[size++]=i;
		int j=i*2;
		for(j;j<=1000000;j+=i)
			s[j]=1;
	}
}
void geteuler()
{
	int i;
	phi[1]=1;
	for(i=1;i<=1000000;i++)
	{
		int j;
		for(j=0;j<size&&prime[j]*i<=1000000;j++){
			if(i%prime[j]==0){
				phi[prime[j]*i]=prime[j]*phi[i];
				break;
			}
			else{
				phi[prime[j]*i]=phi[i]*(prime[j]-1);
			}
		}
	}
	for(i=3;i<=1000000;i++)
		phi[i]+=phi[i-1];
}
int main()
{
	getprime();
	geteuler();
	int n;
	while(scanf("%d",&n)!=EOF,n)
	{

		printf("%I64d\n",phi[n]);
	}
	return 0;

}

可是在网上找了一个牛人的,居然47MS,牛!

代码如下:

#include <stdio.h>
#define len 1000005
#define le 100000
int phi[len],prime[le];
bool unprime[len];
long long sum[len];
void oular(){
    int i,j,k;
    for(i=2,k=0;i<len;i++){
        if(!unprime[i]){
            prime[k++]=i;
            phi[i]=i-1;
        }
        for(j=0;j<k&&prime[j]*i<len;j++){
            unprime[prime[j]*i]=true;
            if(i%prime[j])
                phi[prime[j]*i]=phi[i]*(prime[j]-1);
            else{
                phi[prime[j]*i]=phi[i]*prime[j];
                break;
            }
        }
    }
}
int main(void){
    int i,n;
    oular();
    for(i=1;i<len;i++)
        sum[i]=sum[i-1]+phi[i];
    while(scanf("%d",&n)==1&&n)
        printf("%lld\n",sum[n]);
    return 0;
}

说明高手很懂得优化!!!学到了很多,

posted @ 2011-05-17 20:38  Ac_smile  阅读(487)  评论(1编辑  收藏  举报