线段树
2026-06-20 13:46:53
发布于:浙江
线段树的构建:
#define int long long
void build(int p, int l, int r){ // 根节点 左节点 右节点
// 将左端点和右端点的数据放入p节点下
tree[p].l = l
tree[p].r = r;
if (l == r){ // 如果是叶子节点 (当左节点=右节点时,是最后一层)
tree[p].value = arr[l]; // 放入值,放入arr[r]也是一个道路
return;
}
int mid = (l + r) / 2;
build(p * 2, l, mid); // 构建左子树
build(p * 2 + 1, mid + 1, r); // 构建右子树
tree[p].value = tree[p * 2].value + tree[p * 2 + 1].value; // 回溯
}
单点修改:
void Pointupdate(int p, int x, int z){ // 根节点 需要修改的节点 需要修改的值
if (tree[p].l == tree[p].r){// 对于找到的位置进行修改(给x的位置增加)
tree[p].value += z;
return;
}
int mid = (tree[p].l + tree[p].r) / 2; // 二分范围:当前节点左右 去划分
if (x <= m) Pointupdate(p * 2, x, z); // 如果需要修改的右半边范围正好包含
else if(x > mid) Pointupdate(p * 2 + 1, x, z);
tree[p].value = tree[p * 2].value + tree[p * 2 + 1].value; // 回溯
}
区间查询:
int query(int p, int x, int y){ // 根节点 查询区间左 查询区间右
if (x <= tree[p].l && y >= tree[p].r){
// 范围p下标包含的值
return tree[p].value;
}
int mid = (tree[p].l + tree[p].r) / 2; // 二分范围
int flag = 0; //记录总和
if (x <= mid) //如果需要修改的范围真好包含
flag += query(p * 2, x, y); //去左子树取值
if (y > mid) //如果需要修改的范围正好包含
flag += query(p * 2 + 1, x, y) //去右子树取值
return flag;
}
懒标记(Lazy Tag)区间修改:
struct node{ // 结构体的形式构建线段树
int l, r, w; // 左节点的起始点 右节点终点(l->r:p节点所包含的范围)
int lazy_tag; // 懒标记
};
void Zoneupdate(int p, int x, int y, int z){
// 根节点 需要修改的范围 需要修改的值
if (x <= tree[p].l && y >= tree[p].r){
tree[p].w += (tree[p].r - tree[p].l + 1) * z; // 对于找到位置进行修改(给x的位置增加)
tree[p].lazy_tag += z;// 懒标记同样增加
return;
}
lazy_transport(p); // 懒标记下传
int mid = (tree[p].l + tree[p].r) / 2; // 当前节点左右 去划分
// 查询当前需要找的位置是在左边还是右边
if (x <= mid) Zoneupdate(p * 2, x, y, z);
if (y > mid) Zoneupdate(p * 2 + 1, x, y, z);
tree[p].w = tree[p * 2].w + tree[p * 2 + 1].w; // 回溯
}
void lazy_transport(int p){ // 懒标记下传
if(tree[p].lazy_tag){ // 当前懒标记存在
tree[p * 2].w = tree[p * 2].w + tree[p * 2].r - tree[p * 2].l + 1) * tree[p].lazy_tag; // 将懒标记传给左右节点
tree[p * 2 + 1].w = tree[p * 2 + 1].r - tree[p * 2 + 1].l + 1) * tree[p].lazy_tag;
tree[p * 2].lazy_tag = tree[p * 2].lazy_tag + tree[p].lazy_lag;
tree[p * 2 + 1].lazy_tag = tree[p * 2 + 1].lazy_tag + tree[p].lazy_tag;
tree[p].lazy_tag = 0; // 清空上一层的懒标记 已经传输完毕
}
}
这里空空如也



















有帮助,赞一个