Solutions of Sum of remainders - MarisaOJ: Marisa Online Judge

Solutions of Sum of remainders

Select solution language

Write solution here.


User Avatar nhanmuaairi    Created at    1 likes

Để có thể làm bài này, ta cần có 1 nhận xét: ***Với mỗi số i sao cho n/a = b, thì chuỗi chia dư của nó tạo thành 1 dãy giảm dần với khoảng cách là b.*** Ví dụ: với __n = 20__, thì khi __a = {7, 8, 9, 10}__ thì __b = 2__, khi đó các n%a lần lượt là __{6, 4, 2, 0}__ Quan sát ta có thể thấy dãy trên hoàn toàn đúng với nhận xét vừa rồi, nhưng tại sao lại như vậy? Ta có $$ n = a \cdot b + r $$ Đặt:$$ r_1 = r - k; $$ $$ n = a \cdot b + r_1 + b$$ $$ n = (a + 1) \cdot b + r_1 $$ Khi này n và b là cố định nên khi a tăng 1 đơn vị, thì r sẽ giảm b đơn vị Vậy nên việc của chúng ta chỉ là chia đoạn từ 1 đến n thành các đoạn sao cho mỗi giá trị a trong đoạn đó thì n/a cố định (=b). Câu hỏi ở đây là chúng ta có bao nhiêu đoạn được tạo ra??? Đáp án ở đây chỉ có khoảng 2√(n). Ta sẽ xét các giá trị a từ 1 đến √(n). Với a = 1 thì b = n; a = 2 thì b = n/2 Điều này có nghĩa là với giá trị a từ n đến n/2+1 thì b = 1. Tương tự với các giá trị khác thì đến khi a = √(n) thì khi đó ta đã có được khoảng √(n) đoạn tương ứng. Tương tự khi a = √(n) + 1 đến n. Vậy ta sẽ có được khoảng 2√(n) đoạn. Khi có giá trị đầu và cuối của 1 dãy quy luật, nếu bạn đã học qua lớp 6 thì bạn sẽ biết đến công thức: $$\frac{(r+l)\cdot(n)}{2}$$ Với l, r là giá trị đầu tiên, cuối cùng của dãy, n là số lượng phần tử. Lấy vị dụ đầu tiên, bạn sẽ thấy $$\frac{(6+0)\cdot(4)}{2} = 0 + 2 + 4 + 6 = 12$$ Việc cuối cùng chỉ là code thôi. #include<bits/stdc++.h> #define ll long long using namespace std; const ll MOD = 1e9 + 7; ll n, m, l, r, d, id, sum = 0, pre, suf, lim; int main(){ ios_base::sync_with_stdio(false); cin.tie(nullptr) cin >> n >> m; lim = min(n, m); r = 0; while(r < lim){ l = r + 1; id = n / l; r = min(n / id, lim); d = r - l + 1; pre = n % l; suf = n % r; d %= MOD; sum = (sum + (((suf + pre) % MOD * d) % MOD * 500000004ll) % MOD) % MOD; } cout <<(sum + ((max(0ll, m - n) % MOD) * (n % MOD)) % MOD) % MOD; return 0; } Trong đó 500000004 = 2^-1 mod(1e9+7)