随笔 - 3  文章 - 1  评论 - 0  阅读 - 50

线段树模板

线段树模板:

/* 线段树 */
#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;
}
posted on   EasonLikeMath  阅读(1)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示