题意:求[n/1]+[n/2]+[n/3]+..+[n/n]。
直接暴力会超时,我们采用枚举商的做法。
以 n=15 为例,
i 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
n/i 15 7 5 3 3 2 2 1 1 1 1 1 1 1 1
用 l 和 r 来代表每次枚举商的两侧端点,不断更新。找找规律就好。
比如说一开始 l=r=n,n/2=7,更新 l 为 7,那么 r-l 这段内是同一个数,这个数是 n/(l+1).
除以 2 之后应该除以什么呢?这个地方是关键,经过观察应是这个除数应是 n/l+1。因为只有这样才能保证 l 最后一直更新到 1。
#include<stack>
#include<set>
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<queue>
#include<cstring>
#include<string>
#include<map>
using namespace std;
int main(){
//freopen("a.txt", "r", stdin);
int n, t; cin >> t;
for(int cas = 1; cas <= t; cas++){
scanf("%d", &n);
long long l = n, r = n, ans = 0, x = 2;
while(l != 1){
l = n/x;
x = n/l+1;
ans += (n/(l+1))*(r-l);
r = l;
//cout << ans << endl;
}
printf("Case%d: %lldn", cas, ans+n);
}
return 0;
}