[UVA]10830 A New Function
题意
计算1~n所有数的除1和这个数本身的约数的和。
\(n\le 2e9\)
题解
枚举每个数计算因数是\(O(n\sqrt{n})\)的,会超时。
考虑改成枚举因数,计算有多少个数是i的倍数,显然有\(\frac{n}{i}\)个。
每个因数对于答案的贡献为\(i * (\lfloor\frac{n}{i}\rfloor-1)\)(需要减去自身)。
这样是\(O(n)\)的,也会超时。
然后注意到在i增加的时候,假如后面这个东西是定值,\(i + (i + 1) + (i + 2)+\dots\)可以用求和公式计算,后面这个东西是数论分块,一块里面的东西是定值。
所以直接用数论分块进行枚举就行了,复杂度是\(O(\sqrt{n})\)。
#include <bits/stdc++.h>
#define int long long
#define Mid ((l + r) >> 1)
#define lson (rt << 1)
#define rson (rt << 1 | 1)
using namespace std;
int read(){
char c; int num, f = 1;
while(c = getchar(),!isdigit(c)) if(c == '-') f = -1; num = c - '0';
while(c = getchar(), isdigit(c)) num = num * 10 + c - '0';
return f * num;
}
int n, cnt;
void work() {
if(n == 0) exit(0);
int ans = 0, l, r;
for(l = 2; l <= n; l = r + 1) {
r = n / (n / l);
ans += (r + l) * (r - l + 1) / 2 * (n / l - 1);
}
printf("Case %lld: %lld\n", ++cnt, ans);
}
signed main()
{
while(cin >> n) work();
return 0;
}