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;
}
 
                    
                 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号