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; }
说明高手很懂得优化!!!学到了很多,