比赛 2025暑期集训第2场 评测结果 AAAAAAAAAA
题目名称 序列操作 最终得分 100
用户昵称 OTTF 运行时间 2.179 s
代码语言 C++ 内存使用 11.73 MiB
提交时间 2025-06-29 17:02:37
显示代码纯文本

#include <algorithm>
#include <cstdio>
#include <iostream>

using namespace std;

constexpr int N = 114514;

int n;
int m;
int nums[N];

struct node {
	int len;
	int num[2][4]; // sum left right together
	int become;
	int change;

	friend node operator+ (node one, node two);
};

node zero;

node operator+ (node one, node two) {
	node res;
	res.len = one.len + two.len;
	res.become = -1;
	res.change = 0;
	
	for (int i = 0; i < 2; i++) {
		res.num[i][0] = one.num[i][0] + two.num[i][0];
		res.num[i][1] = one.num[i][1] + (one.num[i][1] == one.len) * two.num[i][1];
		res.num[i][2] = two.num[i][2] + (two.num[i][2] == two.len) * one.num[i][2];
		res.num[i][3] = max ({one.num[i][3], two.num[i][3], one.num[i][2] + two.num[i][1]});
	}

	return res;
}

node tree[N * 4];

inline int lson (int now) {
	return now * 2;
}

inline int rson (int now) {
	return now * 2 + 1;
}

void build (int now, int nowl, int nowr) {
	if (nowl == nowr) {
		tree[now].len = 1;
		for (int i = 0; i < 2; i++) {
			for (int j = 0; j < 4; j++) {
				tree[now].num[i][j] = (nums[nowl] == i);
			}
		}
		tree[now].become = -1;
		tree[now].change = 0;
		return;
	}

	int m = (nowl + nowr) / 2;
	build (lson (now), nowl, m);
	build (rson (now), m + 1, nowr);
	tree[now] = tree[lson (now)] + tree[rson (now)];
	tree[now].become = -1;
	tree[now].change = 0;
}

void giveMark (int now, int mark) {
	if (mark <= 1) {
		tree[now].become = mark;
		tree[now].change = 0;
		for (int i = 0; i < 2; i++) {
			for (int j = 0; j < 4; j++) {
				tree[now].num[i][j] = (mark == i) * tree[now].len;
			}
		}
	}
	else {
		tree[now].change ^= 1;
		swap (tree[now].num[0], tree[now].num[1]);
	}
}

void pushDown (int now) {
	if (tree[now].become != -1) {
		giveMark (lson (now), tree[now].become);
		giveMark (rson (now), tree[now].become);
	}
	if (tree[now].change) {
		giveMark (lson (now), 2);
		giveMark (rson (now), 2);
	}
	tree[now].become = -1;
	tree[now].change = 0;
}

void update (int now, int nowl, int nowr, int l, int r, int num) {
	if (l <= nowl && nowr <= r) {
		giveMark (now, num);
		return;
	}

	pushDown (now);

	int m = (nowl + nowr) / 2;
	if (l <= m) {
		update (lson (now), nowl, m, l, r, num);
	}
	if (m + 1 <= r) {
		update (rson (now), m + 1, nowr, l, r, num);
	}

	tree[now] = tree[lson (now)] + tree[rson (now)];
}

node query (int now, int nowl, int nowr, int l, int r) {
	if (l <= nowl && nowr <= r) {
		return tree[now];
	}

	pushDown (now);

	int m = (nowl + nowr) / 2;
	
	if (r <= m) {
		return query (lson (now), nowl, m, l, r);
	}
	if (m + 1 <= l) {
		return query (rson (now), m + 1, nowr, l, r);
	}
	return query (lson (now), nowl, m, l, r) + query (rson (now), m + 1, nowr, l, r);
}

int main () {
	
	freopen ("sequence.in", "r", stdin);
	freopen ("sequence.out", "w", stdout);

	cin >> n >> m;
	for (int i = 1; i <= n; i++) {
		cin >> nums[i];
	}
	build (1, 1, n);

	int op, l, r;
	for (int i = 1; i <= m; i++) {
		cin >> op >> l >> r;
		l++;
		r++;
		if (op <= 2) {
			update (1, 1, n, l, r, op);
		}
		else {
			node res = query (1, 1, n, l, r);
			if (op == 3) {
				cout << res.num[1][0] << endl;
			}
			else {
				cout << res.num[1][3] << endl;
			}
		}

	}
	
	return 0;
}