http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2421
代码及其注释:
#include <iostream> #include <cstdio> #include <string> #include <cstring> #include <cmath> #include <algorithm> #include <queue> #define ll long long #define lint long long using namespace std; const int N=4000005; int phi[N];//phi[k] 表示从1到k 和k互质的数有几个 ll f[N],sum[N];//f[k] 表示从1到k-1 依次求和k的最大公约数 所以最大公约数的总和 void phin(int n=N-1) { memset(phi,0,sizeof(phi)); phi[1]=1; for(int i=2;i<=n;++i) if(!phi[i]) { for(int j=i;j<=n;j=j+i) { if(!phi[j]) phi[j]=j; phi[j]=phi[j]/i*(i-1); } } } int main() { //freopen("data.in","r",stdin); phin(); memset(f,0,sizeof(f)); memset(sum,0,sizeof(sum)); for(int i=1;i<N;++i) for(int j=i+i,l=2;j<N;j=j+i,++l) { f[j]+=(ll)phi[l]*(ll)i;//这里的phi[l]表示小于j的数中与j的最大公约数是i的数的个数 } for(int i=1;i<N;++i) sum[i]=f[i]+sum[i-1]; int k; while(cin>>k) { if(!k) break; cout<<sum[k]<<endl; } return 0; }