25pts求调
查看原帖
25pts求调
445650
I_never_left楼主2024/8/8 20:31
#include <bits/stdc++.h>

using namespace std;

typedef long long LL;

const int N = 200010;

int n, m;
struct Node {
	int l, r;
	int sum, k;
	int maxl, maxm, maxr;
} tr[N << 2];

void pushup(int u) {
	tr[u].sum = tr[u << 1].sum + tr[u << 1 | 1].sum;
	if(tr[u << 1].maxl == (tr[u << 1].r - tr[u << 1].l + 1))
		tr[u].maxl = tr[u << 1].r - tr[u << 1].l + 1 + tr[u << 1 | 1].maxl;
	else tr[u].maxl = tr[u << 1].maxl;
	if(tr[u << 1 | 1].maxr == (tr[u << 1 | 1].r - tr[u << 1 | 1].l + 1))
		tr[u].maxr = tr[u << 1 | 1].r - tr[u << 1 | 1].l + 1 + tr[u << 1].maxr;
	else tr[u].maxr = tr[u << 1 | 1].maxr;
	tr[u].maxm = max(max(tr[u << 1].maxm, tr[u << 1 | 1].maxm), tr[u << 1].maxr + tr[u << 1 | 1].maxl);
	tr[u].maxm = max({tr[u].maxm, tr[u].maxl, tr[u].maxr});
}

void pushdown(int u) {
	Node &root = tr[u], &L = tr[u << 1], &R = tr[u << 1 | 1];
	if(root.k != -1) {
		L.k = R.k = root.k;
		L.sum = (L.r - L.l + 1) * root.k;
		R.sum = (R.r - R.l + 1) * root.k;
		L.maxl = L.maxm = L.maxr = (L.r - L.l + 1) * (root.k == 1 ? 0 : 1);
		R.maxl = R.maxm = R.maxr = (R.r - R.l + 1) * (root.k == 1 ? 0 : 1);
		root.k = -1;
	}
}

void build(int u, int l, int r) {
	if(l == r) tr[u] = {l, r, 1, -1, 0, 0, 0};
	else {
		tr[u] = {l, r, 0, -1, 0, 0, 0};
		int Mid = (l + r) >> 1;
		build(u << 1, l, Mid);
		build(u << 1 | 1, Mid + 1, r);
		pushup(u);
	}
}

void modify(int u, int l, int r, int y) {
	if(l <= tr[u].l && tr[u].r <= r) {
		tr[u].k = y;
		tr[u].sum = (tr[u].r - tr[u].l + 1) * y;
		tr[u].maxl = tr[u].maxm = tr[u].maxr = (tr[u].r - tr[u].l + 1) * (y == 1 ? 0 : 1);
	} else {
		pushdown(u);
		int Mid = (tr[u].l + tr[u].r) >> 1;
		if(l <= Mid) modify(u << 1, l, r, y);
		if(Mid < r) modify(u << 1 | 1, l, r, y);
		pushup(u);
	}
}

int query1(int u, int l, int r) {
	if(l <= tr[u].l && tr[u].r <= r) return tr[u].sum;
	int Mid = (tr[u].l + tr[u].r) >> 1;
	int sum = 0;
	pushdown(u);
	if(l <= Mid) sum += query1(u << 1, l, r);
	if(Mid < r) sum += query1(u << 1 | 1, l, r);
	return sum;
}

int query0(int u, int l, int r) {
	if(l <= tr[u].l && tr[u].r <= r) return tr[u].r - tr[u].l + 1 - tr[u].sum;
	int Mid = (tr[u].l + tr[u].r) >> 1;
	int sum = 0;
	pushdown(u);
	if(l <= Mid) sum += query0(u << 1, l, r);
	if(Mid < r) sum += query0(u << 1 | 1, l, r);
	return sum;
}

int query2(int u, int l, int r) {
	if(l <= tr[u].l && tr[u].r <= r) return tr[u].maxm;
	int Mid = (tr[u].l + tr[u].r) >> 1;
	int maxx = 0;
	pushdown(u);
	if(l <= Mid) maxx = max(maxx, query2(u << 1, l, r));
	if(Mid < r) maxx = max(maxx, query2(u << 1 | 1, l, r));
	return maxx;
}

void work(int l, int r, int l0, int r0) {
	int x = query1(1, l, r);
	if(x == 0) return ;
	modify(1, l, r, 0);
	int L = l0, R = r0 + 1;
	while(L + 1 < R) {
		int Mid = (L + R) / 2;
		if(query0(1, l0, Mid) <= x) L = Mid;
		else R = Mid;
	}
	modify(1, l0, L, 1);
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0), cout.tie(0);
	cin >> n >> m;
	build(1, 1, n);
	while(m --) {
		int ops, l, r, l0, r0;
		cin >> ops >> l >> r;
		if(ops == 0) modify(1, l, r, 0);
		else if(ops == 1) {
			cin >> l0 >> r0;
			work(l, r, l0, r0);
		} else cout << query2(1, l, r) << '\n';
	}
	return 0;
}
2024/8/8 20:31
加载中...