您的位置:首页 > 产品设计 > UI/UE

Farey Sequence(Poj2478)(快速求欧拉函数)

2015-12-18 21:27 411 查看
Farey Sequence

Time Limit: 1000MSMemory Limit: 65536K
Total Submissions: 13883Accepted: 5489
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
2
3
4
5
0

Sample Output
1
3
5
9

  这就是个欧拉函数模板题,只是会遇到超时的问题。
常规的模板函数超时~

#include<stdio.h>
__int64 phi[1000001]; 
__int64 sum[1000001];
int euler(int n)
{
	long long ans=n;
	for(int i=2;i*i<=n;i++)
	{
		if(n%i==0)
		{
			ans=ans/i*(i-1);
			n/=i;
		}
		while(n%i==0)
		{
			n/=i;
		}
	}
	if(n>1)
	    return ans/n*(n-1);
	return ans;
}
int main()
{
	int i,j,n;
	sum[2]=phi[2]=euler(2);
	for(i=3;i<=1000000;i++)
	{
		phi[i]=euler(i);
		sum[i]=phi[i]+sum[i-1];
		
	}
	while(scanf("%d",&n)!=EOF&&n)
	{
		printf("%I64d\n",sum
);
	}
}

参考网上优化代码(110MS)
#include<stdio.h>
int phi[1000001]; 
__int64 sum[1000001];
int euler()	
{
	for(int i=1;i<=1000000;i++)
	{
		phi[i]=i;
	}
	for(int i=2;i<=1000000;i++)
	{
		if(i==phi[i]) //判断如果i是素数 
		{
			for(int j=i;j<=1000000;j+=i)
			{
			    phi[j]=(phi[j]/i)*(i-1);//i是素数并且是j的一个因子,正好满足欧拉函数。 
			}
		}
	}
}
int main()
{
	int i,j,n;
	sum[2]=1; 
	euler();
	for(i=3;i<=1000000;i++)
	{
		sum[i]=phi[i]+sum[i-1];
		
	}
	while(scanf("%d",&n)!=EOF&&n)
	{
		printf("%I64d\n",sum
);
	}
}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: