題目鏈接
/*
題意:給定一個N,求從2~N的最小公倍數的和
類型:數學
分析:兩種姿勢可以A題,但是用時相差很大
1.用類似埃氏篩選法,處理出前綴和4000+ms
2.用類似因式分解的方法,分成兩部分,sqrt(N)前和後,後的可以用求和公式,前的
用n/i*i求出來20ms
*/
//第一種方法
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
using namespace std;
const int maxn = 20000001;
typedef long long ll;
ll ans[maxn];
int main()
{
for(int i=2;i<maxn;i++){
for(int j=i;j<maxn;j+=i){
ans[j]+=i;
}
ans[i]+=ans[i-1];
}
int n;
while(~scanf("%d",&n)){
printf("%lld\n",ans[n]+n-1);
}
return 0;
}
//第二種方法(隊友剛開始吃TLE,一氣之下寫了個20ms的代碼QAQ)
#include <iostream>
#include<cstdio>
using namespace std;
int main()
{
long long n;
while(scanf("%lld",&n)!=EOF){
if(n==0)break;
long long sum=0;
long long old=n;
long long i;
for(i=2ll;i*i<=n;i++){
long long old=n/(i-1);
long long neww=n/i;
sum+=(n/i)*i;
sum+=(i-1)*(old+neww+1)*(old-neww)/2;
}
i-=1ll;
if(n/i!=i){
sum+=(n/i)*i;
}
printf("%lld\n",sum+n-1);
}
return 0;
}