sicily 1089. Farey Sequence

#include <iostream>            //欧拉函数, 给定n,求φ(1)到φ(n)的和
using namespace std;

const int max_n=1000000;
long long phi[max_n+2],sum[max_n+2]; //这里数组空间起码要稍微大于max_n
void phi_table() //欧拉函数表
{

for(int i=2;i<=max_n;++i)
phi[i]=0;
phi[1]=1;
for(int i=2;i<=max_n;++i)
if(!phi[i])
{
for(int j=i;j<=max_n;j+=i)
{
if(!phi[j])
phi[j]=j;
phi[j]=phi[j]/i*(i-1);
}
}
}
int main()
{
phi_table();
for(int i=2;i<=max_n;++i)
sum[i]=phi[i]+sum[i-1];
int n;
while(cin>>n&&n)
cout<<sum[n]<<endl;
return 0;
}

/*

小插曲:之前一直RE,把全部解打印出来,与正确答案完全一样,与以前写过的程序相比较,实在找不出有什么地方可以导致RE的,
提交了不下十遍,无奈在网上搜索了一下,刚好也有RE的,他居然是这么解决的:把cin,cout都用scanf,printf
晕...没想到果然行了,直呼神奇啊.
经测试,如果只把cout改成printf,而还是保留cin>>n,(n是int类型)愣也是RE,这下我无语了.
不经意间发现,原来真正的问题出在数组的声明上:long long phi[max_n],sum[max_n];
我虽然把max_n 有意识地定义为1000002,比 n的最大值稍大,
但却忽略了数组的最大下标就是max_n,起码长度要大于max_n吧,栽在这里了....

*/

 

 

 

 

先打素数表,再筛法求欧拉函数值
#include <iostream>            //筛法求欧拉函数值, Fn中元素的个数即为1-n的欧拉函数之和。
using namespace std;
const int max_n=1000000;
bool p[max_n+1]; //素数表
long long phi[max_n+1],sum[max_n+1]; //sum[]要声明为long long,当n较大时,sum[n]会超int范围.
//这里欧拉值phi[]如果声明为int,时间是0.1sec,若声明为long long,则是0.2sec

void prime() //筛法打素数表,求出max_n 内的所有素数
{
long long i,j;
p[0]=p[1]=0;
for(i=2;i<=max_n;++i)
p[i]=1;
for(i=2;i<=max_n;++i)
if(p[i]==1)
{
for(j=i*i;j<=max_n;j+=i) //这里j=i*i,所以 j 要声明为long long,否则会溢出
p[j]=0;
}
}
void Euler() //求出max_n 内的所有数的欧拉函数值
{
int i,j;
for(i=1;i<=max_n;++i)
phi[i]=i;
for(i=2;i<=max_n;++i)
if(p[i]==1)
{
for(j=i;j<=max_n;j+=i)
phi[j]=phi[j]/i*(i-1);
}
}
int main()
{
int n;
prime();
Euler();
for(int i=2;i<=max_n;++i)
sum[i]=phi[i]+sum[i-1];
while(cin>>n&&n)
cout<<sum[n]<<endl;
return 0;
}



posted on 2011-07-12 17:07  sysu_mjc  阅读(167)  评论(0编辑  收藏  举报

导航