#3 WA求助
查看原帖
#3 WA求助
582360
UniGravity楼主2023/12/23 14:09

样例可以顺利通过

#include <bits/stdc++.h>
#define int long long
#define lc(x) (x << 1)
#define rc(x) (x << 1 | 1)
using namespace std;

const int N = 800005;

int n, m, a[N];

struct Node {
	int ms, ls, rs;
	int mlp, mrp, lp, rp;
}; 

struct Tree {
	Node maxt, mint;
	int sum;
};

Tree tree[N];
int lazy[N];
int l1[N], r1[N];

inline Tree pushup(Tree l, Tree r) {
	Tree res;
	res.sum = l.sum + r.sum;
	
	// update ms 
	if (l.maxt.ms > r.maxt.ms) {
		res.maxt.ms = l.maxt.ms;
		res.maxt.mlp = l.maxt.mlp;
		res.maxt.mrp = l.maxt.mrp;
	} else {
		res.maxt.ms = r.maxt.ms;
		res.maxt.mlp = r.maxt.mlp;
		res.maxt.mrp = r.maxt.mrp;
	}
	if (l.maxt.rs + r.maxt.ls > res.maxt.ms) {
		res.maxt.ms = l.maxt.rs + r.maxt.ls;
		res.maxt.mlp = l.maxt.rp;
		res.maxt.mrp = r.maxt.lp;
	}
	
	// update ls
	if (l.maxt.ls > l.sum + r.maxt.ls) {
		res.maxt.ls = l.maxt.ls;
		res.maxt.lp = l.maxt.lp;
	} else {
		res.maxt.ls = l.sum + r.maxt.ls;
		res.maxt.lp = r.maxt.lp;
	}
	
	// update rs
	if (r.maxt.rs > r.sum + l.maxt.rs) {
		res.maxt.rs = r.maxt.rs;
		res.maxt.rp = r.maxt.rp;
	} else {
		res.maxt.rs = r.sum + l.maxt.rs;
		res.maxt.rp = l.maxt.rp;
	}
	
	// update ms 
	if (l.mint.ms < r.mint.ms) {
		res.mint.ms = l.mint.ms;
		res.mint.mlp = l.mint.mlp;
		res.mint.mrp = l.mint.mrp;
	} else {
		res.mint.ms = r.mint.ms;
		res.mint.mlp = r.mint.mlp;
		res.mint.mrp = r.mint.mrp;
	}
	if (l.mint.rs + r.mint.ls < res.mint.ms) {
		res.mint.ms = l.mint.rs + r.mint.ls;
		res.mint.mlp = l.mint.rp;
		res.mint.mrp = r.mint.lp;
	}
	
	// update ls
	if (l.mint.ls < l.sum + r.mint.ls) {
		res.mint.ls = l.mint.ls;
		res.mint.lp = l.mint.lp;
	} else {
		res.mint.ls = l.sum + r.mint.ls;
		res.mint.lp = r.mint.lp;
	}
	
	// update rs
	if (r.mint.rs < r.sum + l.mint.rs) {
		res.mint.rs = r.mint.rs;
		res.mint.rp = r.mint.rp;
	} else {
		res.mint.rs = r.sum + l.mint.rs;
		res.mint.rp = l.mint.rp;
	}
	
	return res;
}

inline void pushdown(int x) {
	if (!lazy[x]) return;
	
	int l = lc(x), r = rc(x);
	
	// update lchild
	swap(tree[l].maxt, tree[l].mint);
	tree[l].maxt.ms *= -1;
	tree[l].maxt.ls *= -1;
	tree[l].maxt.rs *= -1;
	tree[l].mint.ms *= -1;
	tree[l].mint.ls *= -1;
	tree[l].mint.rs *= -1;
	
	// update rchild
	swap(tree[r].maxt, tree[r].mint);
	tree[r].maxt.ms *= -1;
	tree[r].maxt.ls *= -1;
	tree[r].maxt.rs *= -1;
	tree[r].mint.ms *= -1;
	tree[r].mint.ls *= -1;
	tree[r].mint.rs *= -1;
	
	lazy[l] ^= 1;
	lazy[r] ^= 1;
	lazy[x] = 0; 
}

inline void build(int x, int l, int r) {
	if (l == r) {
		tree[x].maxt.mlp = tree[x].maxt.mrp = tree[x].maxt.lp = tree[x].maxt.rp = l;
		tree[x].maxt.ms = tree[x].maxt.ls = tree[x].maxt.rs = a[l];
		
		tree[x].mint.mlp = tree[x].mint.mrp = tree[x].mint.lp = tree[x].mint.rp = l;
		tree[x].mint.ms = tree[x].mint.ls = tree[x].mint.rs = a[l];
		
		tree[x].sum = a[l];
		return;
	}
	int mid = l + r >> 1;
	build(lc(x), l, mid);
	build(rc(x), mid + 1, r);
	tree[x] = pushup(tree[lc(x)], tree[rc(x)]);
}

inline void update(int x, int l, int r, int pos, int val) {
	if (l == r) {
		a[l] = val;
		
		tree[x].maxt.mlp = tree[x].maxt.mrp = tree[x].maxt.lp = tree[x].maxt.rp = l;
		tree[x].maxt.ms = tree[x].maxt.ls = tree[x].maxt.rs = a[l];
		
		tree[x].mint.mlp = tree[x].mint.mrp = tree[x].mint.lp = tree[x].mint.rp = l;
		tree[x].mint.ms = tree[x].mint.ls = tree[x].mint.rs = a[l];
		
		tree[x].sum = a[l];
		return;
	}
	int mid = l + r >> 1;
	pushdown(x); 
	if (pos <= mid) update(lc(x), l, mid, pos, val);
	else update(rc(x), mid + 1, r, pos, val);
	tree[x] = pushup(tree[lc(x)], tree[rc(x)]);
}

inline void reverse(int x, int l, int r, int pl, int pr) {
	if (pl <= l && r <= pr) {
		swap(tree[x].maxt, tree[x].mint);
		tree[x].maxt.ms *= -1;
		tree[x].maxt.ls *= -1;
		tree[x].maxt.rs *= -1;
		tree[x].mint.ms *= -1;
		tree[x].mint.ls *= -1;
		tree[x].mint.rs *= -1;
		lazy[x] ^= 1;
		return;
	}
	int mid = l + r >> 1;
	pushdown(x);
	if (pl <= mid) reverse(lc(x), l, mid, pl, pr);
	if (mid < pr) reverse(rc(x), mid + 1, r, pl, pr);
	tree[x] = pushup(tree[lc(x)], tree[rc(x)]);
}

inline Tree query(int x, int l, int r, int pl, int pr) {
	if (pl <= l && r <= pr) return tree[x];
	int mid = l + r >> 1;
	pushdown(x);
	if (pl <= mid && mid < pr) {
		Tree lt, rt;
		lt = query(lc(x), l, mid, pl, pr);
		rt = query(rc(x), mid + 1, r, pl, pr);
		return pushup(lt, rt);
	} 
	if (pl <= mid) return query(lc(x), l, mid, pl, pr);
	if (mid < pr) return query(rc(x), mid + 1, r, pl, pr);
}

signed main() {
	scanf("%lld", &n);
	for (int i = 1; i <= n; i++) scanf("%lld", &a[i]);
	build(1, 1, n);
	scanf("%lld", &m);
	int op, l, r, k, k1; 
	int ans, ret;
	Tree t;
	while (m--) {
		scanf("%lld %lld %lld", &op, &l, &r);
		if (op == 0) {
			update(1, 1, n, l, r);
		} else {
			scanf("%lld", &k);
			k1 = k;
			ans = ret = 0;
			while (k) {
				t = query(1, 1, n, l, r);
				ret += t.maxt.ms;
				ans = max(ans, ret);
				reverse(1, 1, n, t.maxt.mlp, t.maxt.mrp);
				l1[k] = t.maxt.mlp;
				r1[k] = t.maxt.mrp;
				k--;
			}
			for (int i = 1; i <= k1; i++) {
				reverse(1, 1, n, l1[i], r1[i]);
			}
			printf("%lld\n", ans);
		}
	}
	return 0;
}
2023/12/23 14:09
加载中...