之前一直在用
void get_eular() {
memset(eul,0,sizeof(eul));
eul[1]=1;
for(int i=2;i<maxlen;i++)
if(!eul[i])
for(int j=i;j<maxlen;j+=i){
if(!eul[j]) eul[j]=j;
eul[j]=eul[j]/i*(i-1);
}
eul[1]=0;eul[2]=1;
for(int i=3;i<maxlen;i++){
eul[i]+=eul[i-1];
}
}
来求前n项的欧拉函数值。。。后来发现了一个比较好的优化。。。。。请看这里的一个讲解
http://www.cnblogs.com/suno/archive/2008/02/04/1064368.html
然后按照优化方案来写程序。。。进入了100ms以内了。。。。嗨皮。。
#include <iostream>
#include <cstdio>
#include<cstring>
using namespace std;
const int maxlen=1000010;
long long eul[maxlen];
int pri[maxlen],f[maxlen],isprim[maxlen],p=0;
inline void get_prim(){
memset(isprim,1,sizeof(isprim));
for(int i=2;i<maxlen;i++){
if(isprim[i]) pri[p++]=i;
for(int j=0;j<p && i*pri[j]<maxlen;j++){
int k=pri[j]*i;
isprim[k]=0,f[k]=pri[j]; // 得到k的最小素因子
if(i%pri[j]==0) break;
}
}
}
inline void get_eul(){
for(int i=2;i<maxlen;i++)
if(isprim[i]) eul[i]=i-1;
else{
int k=i/f[i];
if(k%f[i]==0) eul[i]=eul[k]*f[i];
else eul[i]=eul[k]*(f[i]-1);
}
for(int i=3;i<maxlen;i++)
eul[i]+=eul[i-1];
}
int main(int argc, char** argv) {
int m;
get_prim();
get_eul();
while(scanf("%d",&m) && m)
printf("%lld\n",eul[m]);
return 0;
}