Luo Gu 2261: remainder sum
Description of the meaning of problems
- Determined \ (\ sum_ {i = 1} ^ nk \ mod \ i \) .
data range
- \(n,k\leq 10^9\)。
Thinking
We know that \ (A \ B% = A - \ lfloor \ FRAC {A} {B} \ rfloor * B \) .
- So we can rewrite the formula \ (\ sum_ {i = 1 } ^ nk- \ lfloor \ frac {k} {i} \ rfloor * i = n * k- \ sum_ {i = 1} ^ ni * \ lfloor \ FRAC {K} I {} \ rfloor \) .
- The problem would be transformed into a request \ (\ sum_ = {I}. 1 Ni * ^ \ lfloor \ FRAC {K} I {} \ rfloor \) .
Make a table look.
Take \ (k = 5, n = 8 \) better.
i=1 | i=2 | i=3 | i=4 | i=5 | i=6 | i=7 | i=8 |
---|---|---|---|---|---|---|---|
5 | 2 | 1 | 1 | 1 | 0 | 0 | 0 |
- We can find that in fact there are a lot \ (\ lfloor \ frac {n } {i} \ rfloor \) is the same.
- Thought it is possible to do with the block.
- Left border enumeration block \ (L \) , the right boundary \ (R & lt = \ lfloor \ FRAC {K} {\ lfloor \ FRAC {K} I {} \} rfloor \ rfloor \) .
- Such block about \ (\ sqrt {n} \ ) a.
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n, k, ans;
int main()
{
scanf("%lld%lld", &n, &k);
ans += n * k;
for(ll l = 1, r; l <= n; l = r + 1)
{
if(k / l != 0) r = min(k/(k/l), n);
else r = n; //当左端点大于k的时候,直接跳过
ans -= (r-l+1) * (l+r)/2 * (k/l);
} puts("");
printf("%lld\n", ans);
return 0;
}