一、题目描述
样例
样例输入
5 10
2 6 6 1 1
2 1 4
1 2 5 10
2 1 3
2 2 3
1 2 2 8
1 2 3 7
1 4 4 10
2 1 2
1 4 5 6
2 3 4
样例输出
15
34
32
33
50
二、算法分析说明与代码编写指导
如果不了解树状数组,建议先阅读之前的题解:
https://blog.csdn.net/COFACTOR/article/details/104199313
https://blog.csdn.net/COFACTOR/article/details/104206182
b[i] += i * d 一开始我把 += 写成 = 而且没有计算 d = arr[i] - arr[i - 1] 而是直接把右边写成 i * a[i] 害得我卡在样例很久,靠。
三、AC 代码
#include<cstdio>
#pragma warning(disable:4996)
template<class _Ty> class Binary_Index_Tree_D {
private:
_Ty* a, * b; size_t n;
size_t lowbit(const size_t& x) const { return x & (~x + 1); }
_Ty at_b(size_t N) const {
_Ty sum = 0;
while (N) { sum += b[N], N -= lowbit(N); }
return sum;
}
public:
Binary_Index_Tree_D(const size_t& Size) {
a = new _Ty[Size + 2](), b = new _Ty[Size + 2](), n = Size;
}
Binary_Index_Tree_D(const _Ty* arr, const size_t& Size) {
a = new _Ty[Size + 2](), b = new _Ty[Size + 2](), n = Size; _Ty d;
for (size_t i = 1, j; i <= n; ++i) {
d = arr[i] - arr[i - 1], a[i] += d, b[i] += i * d, j = i + lowbit(i);
if (j <= n) { a[j] += a[i]; b[j] += b[i]; }
}
}
~Binary_Index_Tree_D() { delete[] a; delete[] b; }
void add(size_t pos, const _Ty& val) {
_Ty val1 = pos * val;
while (pos <= n) { a[pos] += val, b[pos] += val1, pos += lowbit(pos); }
}
_Ty at(size_t N) const {
_Ty sum = 0;
while (N) { sum += a[N], N -= lowbit(N); }
return sum;
}
_Ty prefix_sum(const size_t& N) const { return (N + 1) * at(N) - at_b(N); }
void range_add(const size_t& L, const size_t& R, const _Ty& val) {
add(L, val), subtract(R + 1, val);
}
void range_subtract(const size_t& L, const size_t& R, const _Ty& val) {
subtract(L, val), add(R + 1, val);
}
_Ty range_sum(const size_t& L, const size_t& R) const { return prefix_sum(R) - prefix_sum(L - 1); }
size_t size() const { return n; }
void subtract(size_t pos, const _Ty& val) {
_Ty val1 = pos * val;
while (pos <= n) { a[pos] -= val, b[pos] -= val1, pos += lowbit(pos); }
}
};
unsigned m, q; unsigned long long n, l, r; long long a[1000002], x;
int main() {
scanf("%llu%u", &n, &q); ++q;
for (unsigned long long i = 1; i <= n; ++i) { scanf("%lld", &a[i]); }
static Binary_Index_Tree_D<long long> b(a, n);
while (--q) {
scanf("%u", &m);
switch (m) {
case 1:
scanf("%llu%llu%lld", &l, &r, &x); b.range_add(l, r, x);
continue;
default:
scanf("%llu%llu", &l, &r); printf("%lld\n", b.range_sum(l, r));
}
}
return 0;
}