String27 @ 2024-07-09 17:51:23
#include <iostream>
#include <algorithm>
using namespace std;
struct Node {
int first, last;
int len;
int sum; //the number of 1 in this node
int value[3];
int lmax[3];
int rmax[3];
int lazyTag;
int reversed;
};
const int N = 1e6 + 5;
int n, m;
int a[N];
Node tree[N << 2];
/*
void debug(int p)
{
cerr << "test:\n";
cerr << tree[p].first << ' ' << tree[p].last << ' ' << tree[p].len << ' ' << tree[p].sum << ' ';
cerr << tree[p].value[1] << ' ' << tree[p].lmax[1] << ' ' << tree[p].rmax[1] << ' ' << tree[p].lazyTag << ' ' << tree[p].reversed << '\n';
}
*/
void maintain(int p)
{
tree[p].sum = tree[p << 1].sum + tree[p << 1 | 1].sum;
for (int i = 0; i < 2; i++) {
tree[p].lmax[i] = tree[p << 1].lmax[i] + (tree[p << 1].lmax[i] == tree[p << 1].last - tree[p << 1].first + 1 ? tree[p << 1 | 1].lmax[i] : 0);
tree[p].rmax[i] = tree[p << 1 | 1].rmax[i] + (tree[p << 1 | 1].rmax[i] == tree[p << 1 | 1].last - tree[p << 1 | 1].first + 1 ? tree[p << 1].rmax[i] : 0);
tree[p].value[i] = max(max(tree[p << 1].value[i], tree[p << 1 | 1].value[i]), tree[p << 1].rmax[i] + tree[p << 1 | 1].lmax[i]);
}
}
void pushDown(int p)
{
if (~tree[p].lazyTag) {
int tmp = tree[p].lazyTag;
//set the tags
tree[p << 1].lazyTag = tree[p << 1 | 1].lazyTag = tree[p].lazyTag;
tree[p].lazyTag = -1;
tree[p].reversed = tree[p << 1].reversed = tree[p << 1 | 1].reversed = 0;
//update the number of 1 in lson and rson
tree[p << 1].sum = tree[p << 1].len * tmp;
tree[p << 1 | 1].sum = tree[p << 1 | 1].len * tmp;
//update the other variables
for (int i = 0; i < 2; i++) {
tree[p << 1].value[i] = tree[p << 1].lmax[i] = tree[p << 1].rmax[i] = tree[p << 1].len * (i == tmp);
tree[p << 1 | 1].value[i] = tree[p << 1 | 1].lmax[i] = tree[p << 1 | 1].rmax[i] = tree[p << 1 | 1].len * (i == tmp);
}
}
if (tree[p].reversed) {
//set the tags
tree[p].reversed = 0;
if (~tree[p << 1].lazyTag) {
//if the tag of lson does not equal to -1
//reverse the tag
tree[p << 1].lazyTag ^= 1;
} else {
//the tag of lson equals to -1
//set the reverse tag
tree[p << 1].reversed ^= 1;
}
if (~tree[p << 1 | 1].lazyTag) {
tree[p << 1 | 1].lazyTag ^= 1;
} else {
tree[p << 1 | 1].reversed ^= 1;
}
//reverse the sum tag
tree[p << 1].sum = tree[p << 1].len - tree[p << 1].sum;
tree[p << 1 | 1].sum = tree[p << 1 | 1].len - tree[p << 1 | 1].sum;
//reverse the other variables
swap(tree[p << 1].value[0], tree[p << 1].value[1]);
swap(tree[p << 1].lmax[0], tree[p << 1].lmax[1]);
swap(tree[p << 1].rmax[0], tree[p << 1].rmax[1]);
swap(tree[p << 1 | 1].value[0], tree[p << 1 | 1].value[1]);
swap(tree[p << 1 | 1].lmax[0], tree[p << 1 | 1].lmax[1]);
swap(tree[p << 1 | 1].rmax[0], tree[p << 1 | 1].rmax[1]);
}
}
void build(int l, int r, int p)
{
tree[p].first = l;
tree[p].last = r;
tree[p].len = r - l + 1;
tree[p].lazyTag = -1;
if (l == r) {
tree[p].value[a[l]] = tree[p].lmax[a[l]] = tree[p].rmax[a[l]] = 1;
if (a[l]) {
tree[p].sum = 1;
}
return;
}
int mid = (l + r) >> 1;
build(l, mid, p << 1);
build(mid + 1, r, p << 1 | 1);
maintain(p);
}
void modify(int l, int r, int p, int op)
{
if (tree[p].first > r || tree[p].last < l) {
return;
}
pushDown(p);
if (l <= tree[p].first && tree[p].last <= r) {
if (op < 2) {
//set the lazy tag
tree[p].lazyTag = op;
//set the other variables
tree[p].sum = tree[p].len * op;
for (int i = 0; i < 2; i++) {
tree[p].value[i] = tree[p].lmax[i] = tree[p].rmax[i] = tree[p].len * (i == op);
}
} else {
//set the reversed tag
if (~tree[p].lazyTag) {
tree[p].lazyTag ^= 1;
} else {
tree[p].reversed ^= 1;
}
//reverse the other variables
tree[p].sum = tree[p].len - tree[p].sum;
swap(tree[p].value[0], tree[p].value[1]);
swap(tree[p].lmax[0], tree[p].lmax[1]);
swap(tree[p].rmax[0], tree[p].rmax[1]);
}
// debug(p);
return;
}
modify(l, r, p << 1, op);
modify(l, r, p << 1 | 1, op);
maintain(p);
// debug(p);
}
int query(int l, int r, int p, int op) {
if (tree[p].first > r || tree[p].last < l) {
return 0;
}
// cerr << "query ";
// debug(p);
pushDown(p);
if (op == 3) {
if (l <= tree[p].first && tree[p].last <= r) {
return tree[p].sum;
}
return query(l, r, p << 1, op) + query(l, r, p << 1 | 1, op);
} else {
int lenL = query(l, r, p << 1, op);
int lenR = query(l, r, p << 1 | 1, op);
int lenM = 0;
if (l <= tree[p << 1].last && tree[p << 1 | 1].first <= r) {
lenM = min(tree[p << 1].last - l + 1, tree[p << 1].rmax[1]) + min(r - tree[p << 1 | 1].first + 1, tree[p << 1 | 1].lmax[1]);
}
return max(max(lenL, lenR), lenM);
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> n >> m;
for (int i = 1; i <= n; i++) {
cin >> a[i];
}
build(1, n, 1);
for (int i = 1; i <= m; i++) {
int op, x, y;
cin >> op >> x >> y;
x++;
y++;
if (op <= 2) {
modify(x, y, 1, op);
} else {
cout << query(x, y, 1, op) << '\n';
}
}
return 0;
}
rt,线段树不知道为什么TLE了