线段树动态开点(包含普通线段树的操作)

动态开点的方法在上一篇blog中,不赘述。

动态开点的线段树也是一个线段树,也可以完成普通线段树的区间查询,也可以采用懒标记的方法区间修改。但是需要注意的是,在查询或者修改的函数中,需要将根节点代表的区间写入形参。根据参数中的根区间确定子区间。

虽然很鸡肋,多学一点是一点。

#include <bits/stdc++.h>
#define lson(k) c[k].lson
#define rson(k) c[k].rson
#define sum(a, b) a + b
using namespace std;
const int N = 310;
struct p{
	int lson, rson, sum, lazy;
};
int cnt;
p c[N * 4];
void init(){
	cnt = 0;
}
int build(){
	++cnt;
	c[cnt].lson = -1;
	c[cnt].rson = -1;
	c[cnt].lazy = 0;
	c[cnt].sum = 0;
	return cnt;
}
void update(int ind, int k, int l, int r, int val){
	if (l == r){
		c[k].sum = val;
		return;
	}
	int mid = (l + r) >> 1;
	if (ind <= mid){
		if (c[k].lson == -1)c[k].lson = build();
		update(ind, c[k].lson, l, mid, val);
	}
	else{
		if (c[k].rson == -1)c[k].rson = build();
		update(ind, c[k].rson, mid + 1, r, val);
	}
	c[k].sum = sum(c[k].lson == -1 ? -1 : c[c[k].lson].sum, c[k].rson == -1 ? -1 : c[c[k].rson].sum);
}
void down(int k){
	if (c[k].lazy){
		if (lson(k) == -1){
			lson(k) = build();
		}
		if (rson(k) == -1){
			rson(k) = build();
		}
		c[lson(k)].lazy += c[k].lazy;
		c[rson(k)].lazy += c[k].lazy;
	}
}
int query(int ll, int rr, int l, int r, int k){
	if (ll <= l && rr >= r){
		return c[k].sum;
	}
	int res = 0;
	int mid = (l + r) >> 1;
	if (c[k].lazy){
		down(k);
		c[lson(k)].sum += c[k].lazy * (mid - l + 1);
		c[rson(k)].sum += c[k].lazy * (r - mid);
		c[k].lazy = 0;
	}
	if (ll <= mid){
		if (c[k].lson == -1)c[k].lson = build();
		res = sum(res, query(ll, rr, l, mid, c[k].lson));
	}
	if (rr > mid){
		if (c[k].rson == -1)c[k].rson = build();
		res = sum(res, query(ll, rr, mid + 1, r, c[k].rson));
	}
	return res;
}
void update(int ll, int rr, int l, int r, int k, int d){
	if (ll <= l && rr >= r){
		c[k].sum += d * (r - l + 1);
		c[k].lazy += d;
		return;
	}
	int mid = (l + r) >> 1;
	if (c[k].lazy){
		down(k);
		c[lson(k)].sum += c[k].lazy * (mid - l + 1);
		c[rson(k)].sum += c[k].lazy * (r - mid);
		c[k].lazy = 0;
	}
	if (ll <= mid){
		if (lson(k) == -1){
			lson(k) = build();
		}
		update(ll, rr, l, mid, lson(k), d);
	}
	if (rr > mid){
		if (rson(l) == -1){
			rson(k) = build();
		}
		update(ll, rr, mid + 1, r, rson(k), d);
	}
	c[k].sum = sum(c[lson(k)].sum, c[rson(k)].sum);
}
int main(){
	int root = build();
	update(1, 5, 1, 10, root, 1);
	update(6, 10, 1, 10, root, 2);
	update(3, 7, 1, 10, root, -1);
	int res = query(1, 10, 1, 10, root);
	printf("%d\n", res);
	return 0;
}
发布了204 篇原创文章 · 获赞 13 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_43701790/article/details/104467626