acwing199.余数之和(除法分块)
生活随笔
收集整理的這篇文章主要介紹了
acwing199.余数之和(除法分块)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
思路
要計算∑i=1nk(modi)\sum _{i = 1} ^ {n}k\pmod {i}∑i=1n?k(modi),可化簡原式=n?k?∑i=1nk/i?i原式 = n * k - \sum _{i = 1} ^ {n} k / i * i原式=n?k?∑i=1n?k/i?i,顯然k/ik / ik/i是一個具有塊狀性質的區間,我們給定了這個塊狀區間的lll,就可以得到r=k/(k/l)r = k / (k / l)r=k/(k/l),由此我們開始確定這一長串塊狀區間的lll,顯然有firstl=1first_l = 1firstl?=1,由此我們可以不斷地去得到所有的塊狀區間的左右端點。
對于所有塊狀區間的∑i=li=rk/i?i\sum _{i = l} ^ {i = r} k / i * i∑i=li=r?k/i?i,顯然k/ik / ik/i是一個定值,由此這個區間的和就是一個等差數列,我們可以用等差數列的求和公式輕松得到這個塊狀區間的和。
最后特判我們的i>ki > ki>k的情況,提前break出循環即可。
代碼
/*Author : lifehappy */ #pragma GCC optimize(2) #pragma GCC optimize(3) #include <bits/stdc++.h> #define mp make_pair #define pb push_back #define endl '\n'using namespace std;typedef long long ll; typedef unsigned long long ull; typedef pair<int, int> pii;const double pi = acos(-1.0); const double eps = 1e-7; const int inf = 0x3f3f3f3f;inline ll read() {ll f = 1, x = 0;char c = getchar();while(c < '0' || c > '9') {if(c == '-') f = -1;c = getchar();}while(c >= '0' && c <= '9') {x = (x << 1) + (x << 3) + (c ^ 48);c = getchar();}return f * x; }void print(ll x) {if(x < 10) {putchar(x + 48);return ;}print(x / 10);putchar(x % 10 + 48); }int main() {// freopen("in.txt", "r", stdin);// freopen("out.txt", "w", stdout);// ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);int n = read(), k = read();ll ans = 1ll * n * k;for(ll l = 1, r; l <= n; l = r + 1) {if(k / l == 0) break;r = min(1ll * n, k / (k / l));ans -= (k / l) * (l + r) * (r - l + 1) / 2;}printf("%lld\n", ans);return 0; }總結
以上是生活随笔為你收集整理的acwing199.余数之和(除法分块)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 常见的电脑报错及解决方法电脑如何报错
- 下一篇: 小A的柱状图