poj 2478 Farey Sequence——快速求欧拉函数

先开始暴搞,然后悲剧地超时了……

题目的大意是:求出正整数1~n内两两互质的数的对数。其中n <= 1,000,000

欧拉函数还有这样的性质:

  设a为N的质因数,若(N % a == 0 && (N / a) % a == 0) 则有E(N)=E(N / a) * a;若(N % a == 0 && (N / a) % a != 0) 则有:E(N) = E(N / a) * (a - 1)。

        预处理用筛选法求得1~n内的所有质数,就可以在比较快的时间内求得1~n内所有数字的欧拉函数。

       在筛选法求质数的过程中,记录合数的最小质因数,这样在求欧拉函数的过程中之需要O(1)的查询时间

先开始又把模版打错,数组开小……哎哟你这个苕货……=.=

a27400 2478 Accepted 17964K 125MS G++ 897B 2011-09-06 09:33:21
#include<cstdio>
#include
<cstdlib>
#include
<cstring>
#include
<cmath>
#include
<algorithm>
#include
<iostream>
#define MAXN 1000000
#define PRIME 80000
typedef unsigned
long long INT;

using namespace std;

INT FS[MAXN
+10];
INT prime[PRIME
+10];
INT top;
INT fac[MAXN
+10];
bool isprime[MAXN+10];

int main(void)
{
INT i,j;
for(i=2;i<=MAXN;i++)
{
if(!isprime[i]) prime[top++]=i;
for(j=0;j<top&&i*prime[j]<=MAXN;j++)
{
INT k
=i*prime[j];
isprime[k]
=true;
fac[k]
=prime[j];
if(i%prime[j]==0) break;
}
}
top
--;
isprime[
1]=true;
for(i=2;i<=MAXN;i++)
{
if(isprime[i])//如果不是素数
{
INT div
=i/fac[i];
FS[i]
=div%fac[i]==0?(FS[div]*fac[i]):(FS[div]*(fac[i]-1));
}
else FS[i]=i-1;
}
for(i=3;i<=MAXN;i++)
FS[i]
+=FS[i-1];
INT n;
while(scanf("%lld",&n)==1)
{
if(!n)
break;
else printf("%lld\n",FS[n]);
}
return 0;
}


posted @ 2011-09-06 09:48  ω 提拉米兔 ℃  阅读(358)  评论(0)    收藏  举报