线段树模板
线段树模板
/* 线段树 */
#include <array>
#include <bits/stdc++.h>
using namespace std;
// 预处理
// #define lc p=p*2
#define lc (p << 1)
// #define rc p=p*2+1
#define rc (p << 1 | 1)
#define N 100005
#define LL long long
array< LL, N > arr;
struct node {
LL l, r, sum, tag;
};
array< node, N * 4 > tree;
// 建树
// p 当前节点 ;[l,r] 当前区间
void build(LL p, LL l, LL r) {
tree[p] = {l, r, arr[l], 0};
// 已经来到叶子节点了
if (l == r) {
// cout<<p<<":
// ["<<tree[p].l<<","<<tree[p].r<<"]-->"<<tree[p].sum<<endl;
return;
}
LL mid = (l + r) >> 1; // 分治
build(lc, l, mid); // 左子树
build(rc, mid + 1, r); // 右子树
tree[p].sum = tree[lc].sum + tree[rc].sum;
// cout<<p<<":
// ["<<tree[p].l<<","<<tree[p].r<<"]-->"<<tree[p].sum<<endl;
}
// 单点修改
void update(LL p, LL x, LL k) {
// 到达叶子节点,且到达目标节点x
if (tree[p].l == x && tree[p].r == x) {
tree[p].sum += k;
return;
}
LL mid = (tree[p].l + tree[p].r) >> 1;
if (x <= mid) {
update(lc, x, k); // 左子树
}
if (x > mid) {
update(rc, x, k); // 右子树
}
tree[p].sum = tree[lc].sum + tree[rc].sum;
}
// 向下更新
void pushdown(LL p) {
if (tree[p].tag != 0) {
tree[lc].sum +=
tree[p].tag * (tree[lc].r - tree[lc].l + 1);
tree[rc].sum +=
tree[p].tag * (tree[rc].r - tree[rc].l + 1);
tree[lc].tag += tree[p].tag;
tree[rc].tag += tree[p].tag;
tree[p].tag = 0;
}
}
// 向上更新
void pushup(LL p) {
tree[p].sum = tree[lc].sum + tree[rc].sum;
}
// 区间修改
void update(LL p, LL l, LL r, LL k) {
if (l <= tree[p].l && tree[p].r <= r) {
tree[p].sum += (tree[p].r - tree[p].l + 1) * k;
tree[p].tag += k;
return;
}
LL m = (tree[p].l + tree[p].r) >> 1;
pushdown(p);
if (l <= m) {
update(lc, l, r, k);
}
if (r > m) {
update(rc, l, r, k);
}
pushup(p);
}
// 区间查询
LL query(LL p, LL x, LL y) {
// 查询区间完全覆盖该区间,则返回
if (x <= tree[p].l && tree[p].r <= y) {
return tree[p].sum;
}
LL mid = (tree[p].l + tree[p].r) >> 1; // 分治
pushdown(p);
LL sum = 0;
if (x <= mid) {
sum += query(lc, x, y);
}
if (y > mid) {
sum += query(rc, x, y);
}
return sum;
}
LL n;
LL m;
int main() {
cin >> n >> m;
for (LL i = 1; i <= n; i++) {
cin >> arr[i];
}
build(1, 1, n);
while (m-- != 0) {
LL option;
LL x;
LL y;
LL k;
cin >> option >> x >> y;
if (option == 2) {
cout << query(1, x, y) << endl;
} else {
cin >> k;
update(1, x, y, k);
}
}
return 0;
}
本文来自博客园,作者:EasonLikeMath,转载请注明原文链接:https://www.cnblogs.com/EasonLikeMath/p/18717949