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;
}
说明高手很懂得优化!!!学到了很多,
浙公网安备 33010602011771号