60分线段树求助
查看原帖
60分线段树求助
573592
Z_章鱼哥楼主2023/5/3 20:26
#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
const int N = 1e6 + 10;
const ll inf = 1e18;

struct Node {
	int l, r;
	ll maxv, lazya, lazyx;	// lazya 维护加,lazyx 维护赋值
} tr[4 * N];
ll n, m, a[N];

void pushdown(int root) {	// 先更新值,然后下放标记
	if (tr[root].lazya) {
		tr[root].maxv += (ll)(tr[root].lazya);

		if (tr[root].l != tr[root].r) {
			tr[root << 1].lazya += (ll)(tr[root].lazya);
			tr[root << 1 | 1].lazya += (ll)(tr[root].lazya);
		}

		tr[root].lazya = 0;
	} else if (tr[root].lazyx != inf) {
		tr[root].maxv = tr[root].lazyx;

		if (tr[root].l != tr[root].r) {
			tr[root << 1].lazyx = tr[root].lazyx;
			tr[root << 1 | 1].lazyx = tr[root].lazyx;
		}

		tr[root].lazyx = inf;
	}
}

void pushup(int root) {	// 先将更新儿子,再更新自己
	pushdown(root << 1);
	pushdown(root << 1 | 1);
	tr[root].maxv = max(tr[root << 1].maxv, tr[root << 1 | 1].maxv);
}

void build(int root, int l, int r) {
	tr[root].l = l, tr[root].r = r;
	tr[root].lazya = 0;
	tr[root].lazyx = inf;

	if (l == r) {
		tr[root].maxv = a[l];
	} else {
		int mid = (l + r) >> 1;
		build(root << 1, l, mid);
		build(root << 1 | 1, mid + 1, r);
		pushup(root);
	}
}

void add(int root, int l, int r, ll x) {	// 先下放标记,再操作
	pushdown(root);
	if (tr[root].l == l && tr[root].r == r) {
		tr[root].lazya += x;
	} else {
		int mid = (tr[root].l + tr[root].r) >> 1;
		if (r <= mid) {
			add(root << 1, l, r, x);
		} else if (l > mid) {
			add(root << 1 | 1, l, r, x);	// 前两种区间不变
		} else {
			add(root << 1, l, mid, x);		// 区间分成两份
			add(root << 1 | 1, mid + 1, r, x);
		}
		pushup(root);
	}
}

void modify(int root, int l, int r, ll x) {
	pushdown(root);
	if (tr[root].l == l && tr[root].r == r) {
		tr[root].lazyx = x;
	} else {
		int mid = (tr[root].l + tr[root].r) >> 1;
		if (r <= mid) {
			modify(root << 1, l, r, x);
		} else if (l > mid) {
			modify(root << 1 | 1, l, r, x);
		} else {
			modify(root << 1, l, mid, x);
			modify(root << 1 | 1, mid + 1, r, x);
		}
		pushup(root);
	}
}

ll query(int root, int l, int r) {	// 先下放标记,再询问
	pushdown(root);
	if (tr[root].l == l && tr[root].r == r) {
		return tr[root].maxv;
	} else {
		int mid = (tr[root].l + tr[root].r) >> 1;
		if (r <= mid) {
			return query(root << 1, l, r);
		} else if (l > mid) {
			return query(root << 1 | 1, l, r);
		} else {
			return max(query(root << 1, l, mid), query(root << 1 | 1, mid + 1, r));
		}
		pushup(root);
	}
}

void solve() {
	cin >> n >> m;
	for (int i = 1; i <= n; i ++) {
		cin >> a[i];
	}

	build(1, 1, n);
	while (m --) {
		ll op, l, r, x;
		cin >> op >> l >> r;

		if (op == 1) {
			cin >> x;
			modify(1, l, r, x);
		} else if (op == 2) {
			cin >> x;
			add(1, l, r, x);
		} else {
			cout << query(1, l, r) << "\n";
		}

		// for (int i = 1; i <= n; i ++) {
		// 	cout << query(1, i, i) << " ";
		// }
		// cout << "\n";
	}
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	int T = 1;
	// cin >> T;

	while (T --) {
		solve();
	}

	return 0;
}
2023/5/3 20:26
加载中...