|
题目来源:http://poj.org/problem?id=3468
线段树做法:https://blog.csdn.net/moon_sky1999/article/details/78428165
详解树状数组区间修改、查询操作的博客:
https://ahackh.ac.cn/2017/06/25/%E8%89%AF%E5%BF%83%E8%AF%A6%E8%A7%A3%E6%A0%91%E7%8A%B6%E6%95%B0%E7%BB%84%E3%81%AE%E5%8C%BA%E9%97%B4%E4%BF%AE%E6%94%B9%E6%B1%82%E5%92%8C%E6%9C%89%E8%BF%99%E7%A7%8D%E6%93%8D%E4%BD%9C/
代码:
#include <cstdio>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#define ll long long
using namespace std;
const int maxn=1e5+10;
ll c1[maxn],c2[maxn],a[maxn];
int n,q;
inline int lb(int x) {
return x & -x;
}
void add1(int x,ll v) {
for (; x <= n; x += lb(x))
c1[x] += v;
}
void add2(int x,ll v) {
for (; x <= n; x += lb(x))
c2[x] += v;
}
ll read(int x) {
ll tot = 0;
for (int i = x; i; i -= lb(i))
tot += x * c1[i] - c2[i];
return tot;
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
while (cin >> n >> q) {
memset(c1, 0, sizeof(c1));
memset(c2, 0, sizeof(c2));
for (int i = 1; i <= n; i++) {
cin >> a[i];
add1(i, a[i] - a[i - 1]);
add2(i, (i - 1) * (a[i] - a[i - 1]));
}
for (int i = 1; i <= q; i++) {
char c;
cin >> c;
if (c == 'Q') {
int l, r;
cin >> l >> r;
cout << read(r) - read(l - 1) << endl;
} else {
int l, r, v;
cin >> l >> r >> v;
add1(l, v);
add1(r + 1, -v);
add2(l, (l - 1) * v);
add2(r + 1, r * (-v));
}
}
}
return 0;
}
|