问题引入
解释:
常规的树状数组 会因为 D=1时退化值O(n2), 因此需要进行分块操作来优化。
- 当 D > sqrt(n) 时,直接常规树状数组操作
- 否则,建立lazy数组,将K值存入lazy[D]
- 计算时,枚举1~sqrt(n)的所有数,看看[L,R]中有几个i,比如[4,6], 6中有三个2, 3中有1个2,因此[4,6]有3-1=2个2 ,只需要将答案加上2*即可
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int lazy[N];
int n, m;
typedef long long LL;
LL tr[N];
int lowbit(int x) {
return x & -x;
}
void add(int x, int c) {
for (int i = x; i <= n; i += lowbit(i))
tr[i] += c;
}
LL sum(int x) {
LL res = 0;
for (int i = x; i; i -= lowbit(i))
res += tr[i];
return res;
}
int main() {
cin >> n >> m;
while (m--) {
int op, l, r;
cin >> op >> l >> r;
if (op == 1) {
if (l <= sqrt(n))
lazy[l] += r;
else {
for (int i = l; i <= n; i += l)
add(i, r);
}
} else {
LL ans = 0;
ans = sum(r) - sum(l - 1);
for (int i = 1; i <= sqrt(n); i++) {
ans += (r / i - (l - 1) / i) * (LL)lazy[i];
}
cout << ans << endl;
}
}
return 0;
}