线段树如何将四种操作合到一起做?
  • 板块学术版
  • 楼主rmxlinux
  • 当前回复7
  • 已保存回复7
  • 发布时间2021/11/19 16:18
  • 上次更新2023/11/4 00:08:51
查看原帖
线段树如何将四种操作合到一起做?
86896
rmxlinux楼主2021/11/19 16:18

Rt,就是将区间增、区间修改为定值、维护最值、维护区间和 放在一起写

我发现至少需要两种pushdown,但我写的query只有一种,所以会有冲突。哪位大佬可以发一个博客链接,或者给一个思路,蒟蒻感激不尽QWQ!

错误代码QAQ

#include <iostream>
#include <cstdio>
#include <cstdlib>
using namespace std;
#define lson (x<<1)
#define rson (x<<1|1)
#define ll long long
struct node {
	ll l, r, sum, add, minn, maxn;
	node() {
		l = r = sum = add = 0 ;
	}
} tree[40005];
ll n, m ;
ll a[10005] ;
void pushdown(ll x) {
	if(tree[x].add) {
		tree[lson].add += tree[x].add ;
		tree[rson].add += tree[x].add ;
		tree[lson].sum += (tree[lson].r - tree[lson].l + 1) * tree[x].add ;
		tree[rson].sum += (tree[rson].r - tree[rson].l + 1) * tree[x].add ;
		tree[lson].maxn += tree[x].add ;
		tree[rson].maxn += tree[x].add ;
		tree[lson].minn += tree[x].add ;
		tree[rson].minn += tree[x].add ;
		tree[x].add = 0 ;
	}
}
void changedown(ll x) {
	if(tree[x].add) {
		tree[lson].add = tree[x].add ;
		tree[rson].add = tree[x].add ;
		tree[lson].sum = (tree[lson].r - tree[lson].l + 1) * tree[x].add ;
		tree[rson].sum = (tree[rson].r - tree[rson].l + 1) * tree[x].add ;
		tree[lson].maxn = max(tree[lson].maxn,tree[x].add) ;
		tree[rson].maxn = max(tree[rson].maxn,tree[x].add) ;
		tree[lson].minn = min(tree[lson].minn,tree[x].add) ;
		tree[rson].minn = min(tree[rson].minn,tree[x].add) ;
		tree[x].add = 0 ;
	}
}
void build(ll x, ll l, ll r) {
	tree[x].l = l ;
	tree[x].r = r ;
	if(l == r) {
		tree[x].sum = a[l] ;
		tree[x].maxn = a[l] ;
		tree[x].minn = a[l] ;
		return ;
	}
	ll mid = (l + r) / 2 ;
	build(lson, l, mid) ;
	build(rson, mid + 1, r) ;
	tree[x].sum = tree[lson].sum + tree[rson].sum ;
	tree[x].maxn = max(tree[lson].maxn, tree[rson].maxn) ;
	tree[x].minn = min(tree[lson].minn, tree[rson].minn) ;
}
void update(ll x, ll l, ll r, ll d) {
	if(l <= tree[x].l && tree[x].r <= r) {
		tree[x].sum += (tree[x].r - tree[x].l + 1) * d;
		tree[x].add += d ;
		tree[x].maxn += d ;
		tree[x].minn += d ;
		return ;
	}
	pushdown(x) ;
	ll mid = (tree[x].l + tree[x].r) / 2 ;
	if(l <= mid) update(lson, l, r, d) ;
	if(mid < r) update(rson, l, r, d) ;
	tree[x].sum = tree[lson].sum + tree[rson].sum ;
}
void change(ll x, ll l, ll r, ll d) {
	if(l <= tree[x].l && tree[x].r <= r) {
		tree[x].sum = (tree[x].r - tree[x].l + 1) * d;
		tree[x].add = d ;
		tree[x].maxn = max(tree[x].maxn,d) ;
		tree[x].minn = min(tree[x].minn,d) ;
		return ;
	}
	changedown(x) ;
	ll mid = (tree[x].l + tree[x].r) / 2 ;
	if(l <= mid) change(lson, l, r, d) ;
	if(mid < r) change(rson, l, r, d) ;
	tree[x].sum = tree[lson].sum + tree[rson].sum ;
}
ll query(ll x, ll l, ll r) {
	if(l <= tree[x].l && tree[x].r <= r)
		return tree[x].sum ;
	pushdown(x) ;
	ll mid = (tree[x].l + tree[x].r) / 2 ;
	ll ans = 0 ;
	if(l <= mid) ans += query(lson, l, r) ;
	if(mid < r) ans += query(rson, l, r) ;
	return ans ;
}
ll querymax(ll x, ll l, ll r) {
	if(l <= tree[x].l && tree[x].r <= r)
		return tree[x].maxn ;
	pushdown(x) ;
	ll mid = (tree[x].l + tree[x].r) / 2 ;
	ll ans = 0 ;
	ll maxx = -9999999999 ;
	if(l <= mid) maxx = max(maxx, querymax(lson, l, r)) ;
	if(mid < r) maxx = max(maxx, querymax(rson, l, r)) ;
	return maxx ;
}
ll querymin(ll x, ll l, ll r) {
	if(l <= tree[x].l && tree[x].r <= r)
		return tree[x].minn ;
	pushdown(x) ;
	ll mid = (tree[x].l + tree[x].r) / 2 ;
	ll ans = 0 ;
	ll minx = 9999999999 ;
	if(l <= mid) minx = min(minx, querymin(lson, l, r)) ;
	if(mid < r) minx = min(minx, querymin(rson, l, r)) ;
	return minx ;
}
int main() {
	cin >> n >> m;
	ll q, x, y, z ;
	for(ll i = 1; i <= n; i++)
		cin >> a[i] ;
	build(1, 1, n) ;
	while(m--) {
		cin >> q ;
		if(q == 1) cin >> x >> y >> z, update(1, x, y, z) ;
		if(q == 2) cin >> x >> y, cout << query(1, x, y) << endl ;
		if(q == 3) cin >> x >> y, cout << querymax(1, x, y) << endl ;
		if(q == 4) cin >> x >> y, cout << querymin(1, x, y) << endl ;
		if(q == 5) cin >> x >> y >> z, change(1, x, y, z) ;
	}
	return 0 ;
}
2021/11/19 16:18
加载中...