线段树[模板]

建树

#define Ln(x) x << 1
#define Rn(x) (x << 1) | 1

struct SegTree{
	int l, r, data, lazy;
	SegTree(int l=0, int r=0, int data=0, int lazy=0):
		l(l), r(r), data(data), lazy(lazy) {};
}tree[maxn*4+10];
int a[maxn];

void pushup(int p){
	tree[p].data = tree[Ln(p)].data + tree[Rn(p)].data;
}
void build(int l, int r, int p){
	tree[p] = SegTree(l, r, 0, 0);
	if(l == r){
            tree[p] = SegTree(l, r, a[l], 0);
            return;
        }
	int mid = (l + r) >> 1;
	build(l, mid, Ln(p));
	build(mid+1, r, Rn(p));
	pushup(p);
}

 


单点修改

void insert(int x, int p, int d){
	int l = tree[p].l, r = tree[p].r;
	if(l == r)
		if(l == x){
            tree[p].data += d;
            return;
            }
	int mid = (l+r) >> 1;
	if (x <= mid)	insert(x, Ln(p), d);
	if (x > mid)	insert(x, Rn(p), d);
	pushup(p);
}

区间修改

void pushdown(int p){
	int lazy = tree[p].lazy;
	tree[Ln(p)].lazy += lazy;
	tree[Rn(p)].lazy += lazy;
	
	tree[Ln(p)].data += lazy * (tree[Ln(p)].r - tree[Ln(p)].l + 1);
	tree[Rn(p)].data += lazy * (tree[Rn(p)].r - tree[Rn(p)].l + 1);
	
	tree[p].lazy = 0;
}
void update(int l, int r, int p, int d){
	int nl = tree[p].l, nr = tree[p].r;
	if(nl >= l && nr <= r){
		tree[p].lazy += d;
		tree[p].data += d*(nr - nl + 1);
		return;
	}
	if(tree[p].lazy)	pushdown(p);
	
	int mid = (nl+nr) >> 1;
	if (l <= mid)	update(l, r, Ln(p), d);
	if (r > mid)	update(l, r, Rn(p), d);
	pushup(p);
}

区间查询

int query(int l, int r, int p){
	int nl = tree[p].l, nr = tree[p].r;
	if(nl >= l && nr <= r)
		return tree[p].data;
	
	if(tree[p].lazy)	pushdown(p);
	int mid = (nl + nr) >> 1;
        int res = 0;
	if(l <= mid)	return query(l, r, Ln(p));
	if(r > mid) 	return query(l, r, Rn(p));
	return res;
}

模板题:luogu 3372

你可能感兴趣的:(数据结构)