Problem C — limit 1 second
Fear Factoring
The Slivians are afraid of factoring; it’s just, well, difficult.
Really, they don’t even care about the factors themselves, just how much they sum to.
We can define F(n) as the sum of all of the factors of n; so F(6) = 12 and F(12) = 28. Your taskis, given two integers a and b with a ≤ b, to calculate
S = X a≤n≤b F(n)
Input
The input consists of a single line containing space-separated integers a and b (1 ≤ a ≤ b ≤ 1e12;b-a ≤ 1e6).
Output
Print S on a single line.
Sample
Input
101 101
Output
102
Input
28 28
Output
56
Input
1 10
Output
87
Input
987654456799 987654456799
Output
987654456800
Input
963761198400 963761198400
Output
5531765944320
Input
5260013877 5260489265
Output
4113430571304040
题目是求从a到b所有数的全部因数之和。
我们思考求从1到b的所有数的因数之和是很好求的,用b除去除从1到b的每个数来求出1-b中有多少个这个数,然后把它们都加起来。由于b过大,因此需要使用整除分块。
整除分块可以求从从i=1到n的n/i的和,对我们而言,这里n/i只不过是块中数的个数,因此ans那里需要加工一下n/i(块中数的个数)(l+r)(r-l+1)/2(等差数列求因子的和),比如3,4,5,6它们块中数的个数都为2,那么就是2(3+4+5+6)
*代码:**
#include<bits/stdc++.h> using namespace std; typedef unsigned long long ll; const int inf = 0x3f3f3f3f; const int mod = 998244353; const double PI = acos(-1.0); const int N = 25; ll get_sum(ll n){ ll ans = 0; for(ll l = 1, r; l <= n; l = r + 1) { r = n / (n / l); ans += (n / l) * (l + r) * (r - l + 1) / 2; } return ans; } int main() { ll a, b; while(~scanf("%lld%lld", &a, &b)) { printf("%lld\n", get_sum(b) - get_sum(a - 1)); } return 0; }