社区讨论

只过 #5 #6 求条

P6242【模板】线段树 3(区间最值操作、区间历史最值)参与者 3已保存回复 3

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
3 条
当前快照
1 份
快照标识符
@miimxcze
此快照首次捕获于
2025/11/28 17:03
3 个月前
此快照最后确认于
2025/11/29 15:15
3 个月前
查看原帖
完全看不出来是哪有问题,完蛋了/ll/ll
CPP
#include <bits/stdc++.h>
using namespace std;
#define il inline
typedef long long ll;
const int N = 5e5 + 5;
int n, m, a[N];
struct node { int len, mxa, mxb, cnt, sec, tgma, tgmb, tgoa, tgob; ll sum; } t[N << 2];
#define lc p << 1
#define rc lc | 1
il void psu(int p) {
	t[p].mxa = max(t[lc].mxa, t[rc].mxa), t[p].mxb = max(t[lc].mxb, t[rc].mxb), t[p].sum = t[lc].sum + t[rc].sum;
	if (t[lc].mxa == t[rc].mxa) t[p].cnt = t[lc].cnt + t[rc].cnt, t[p].sec = max(t[lc].sec, t[rc].sec);
	else if (t[lc].mxa > t[rc].mxa) t[p].cnt = t[lc].cnt, t[p].sec = max(t[lc].sec, t[rc].mxa);
	else t[p].cnt = t[rc].cnt, t[p].sec = max(t[lc].mxa, t[rc].sec);
}
il void upd(int p, int tgma, int tgmb, int tgoa, int tgob) {
	t[p].sum += (ll)tgma * t[p].cnt + (ll)tgoa * (t[p].len - t[p].cnt);
	t[p].mxb = max(t[p].mxb, t[p].mxa + tgmb), t[p].mxa += tgma;
	if (t[p].sec ^ INT_MIN) t[p].sec += tgoa;
	t[p].tgmb = max(t[p].tgmb, t[p].tgma + tgmb), t[p].tgma += tgma;
	t[p].tgob = max(t[p].tgob, t[p].tgoa + tgob), t[p].tgoa += tgoa;
}
il void psd(int p) {
	if (!t[p].tgma && !t[p].tgmb && !t[p].tgoa && !t[p].tgob) return;
	if (t[lc].mxa == t[p].mxa) upd(lc, t[p].tgma, t[p].tgmb, t[p].tgoa, t[p].tgob);
	else upd(lc, t[p].tgoa, t[p].tgob, t[p].tgoa, t[p].tgob);
	if (t[rc].mxa == t[p].mxa) upd(rc, t[p].tgma, t[p].tgmb, t[p].tgoa, t[p].tgob);
	else upd(rc, t[p].tgoa, t[p].tgob, t[p].tgoa, t[p].tgob);
	t[p].tgma = t[p].tgmb = t[p].tgoa = t[p].tgob = 0;
}
void build(int p, int l, int r) {
	t[p].len = r - l + 1;
	if (l == r) return t[p].mxa = t[p].mxb = t[p].sum = a[l], t[p].cnt = 1, t[p].sec = INT_MIN, void();
	int mid = l + r >> 1;
	build(lc, l, mid), build(rc, mid + 1, r), psu(p);
}
void add(int p, int l, int r, int L, int R, int x) {
	if (L <= l && r <= R) {
		t[p].sum += (ll)t[p].len * x, t[p].mxb = max(t[p].mxb, t[p].mxa += x);
		if (t[p].sec ^ INT_MIN) t[p].sec += x;
		t[p].tgmb = max(t[p].tgmb, t[p].tgma += x), t[p].tgob = max(t[p].tgob, t[p].tgoa += x);
		return;
	}
	int mid = l + r >> 1; psd(p);
	if (L <= mid) add(lc, l, mid, L, R, x); if (R > mid) add(rc, mid + 1, r, L, R, x); psu(p);
}
void chkmn(int p, int l, int r, int L, int R, int x) {
	if (t[p].mxa <= x) return;
	if (L <= l && r <= R && t[p].sec < x) {
		int y = t[p].mxa - x;
		t[p].sum -= (ll)t[p].cnt * y, t[p].mxa = x;
		t[p].tgmb = max(t[p].tgmb, t[p].tgma -= y);
		return;
	}
	int mid = l + r >> 1; psd(p);
	if (L <= mid) chkmn(lc, l, mid, L, R, x); if (R > mid) chkmn(rc, mid + 1, r, L, R, x); psu(p);
}
ll qsum(int p, int l, int r, int L, int R) {
	if (L <= l && r <= R) return t[p].sum;
	int mid = l + r >> 1; ll ret = 0; psd(p);
	if (L <= mid) ret += qsum(lc, l, mid, L, R); if (R > mid) ret += qsum(rc, mid + 1, r, L, R);
	return ret;
}
int qmxa(int p, int l, int r, int L, int R) {
	if (L <= l && r <= R) return t[p].mxa;
	int mid = l + r >> 1, ret = INT_MIN; psd(p);
	if (L <= mid) ret = max(ret, qmxa(lc, l, mid, L, R)); if (R > mid) ret = max(ret, qmxa(rc, mid + 1, r, L, R));
	return ret;
}
int qmxb(int p, int l, int r, int L, int R) {
	if (L <= l && r <= R) return t[p].mxb;
	int mid = l + r >> 1, ret = INT_MIN; psd(p);
	if (L <= mid) ret = max(ret, qmxb(lc, l, mid, L, R)); if (R > mid) ret = max(ret, qmxb(rc, mid + 1, r, L, R));
	return ret;
}
int main() {
	ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	cin >> n >> m;
	for (int i = 1; i <= n; i++) cin >> a[i]; build(1, 1, n);
	while (m--) {
		int op, l, r, k; cin >> op >> l >> r;
		if (op == 1) cin >> k, add(1, 1, n, l, r, k);
		else if (op == 2) cin >> k, chkmn(1, 1, n, l, r, k);
		else if (op == 3) cout << qsum(1, 1, n, l, r) << '\n';
		else if (op == 4) cout << qmxa(1, 1, n, l, r) << '\n';
		else cout << qmxb(1, 1, n, l, r) << '\n';
	}
}

回复

3 条回复,欢迎继续交流。

正在加载回复...