Subtask #1过了, 但是0分
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5+3;
#define lp p<<1
#define rp p <<1|1
int n, m, arr[N];
struct node{
int l=-1, r;
//1的个数, 0的个数
int sum1, sum0;
//从左开始1和0的个数
int seml1, seml0;
//从右开始1和0的个数
int semr1, semr0;
//最长的1区间,最长的0区间
int Mxsem1, Mxsem0;
//标记位置
//tag1存哪个数,tag2存是否反转
int tag1 = -1, tag2;
//up
void change(int s1, int s0, int sl1, int sr1, int sl0, int sr0, int mxs1, int mxs0) {
sum1 = s1;sum0 = s0;seml1 = sl1;seml0 = sl0;semr1 = sr1;semr0 = sr0;Mxsem1 = mxs1;Mxsem0 = mxs0;
}
int mid(){return l + r >>1;}
int len() {return r-l + 1;}
}tr[N*4];
void merge(node& x, node y) {
x.change(
//计数
x.sum1+y.sum1, x.sum0+y.sum0,
// 区间1合并
(x.sum0 ? x.seml1 : x.sum1 +y.seml1), (y.sum0 ? y.semr1 :y.sum1 + x.semr1),
// 区间0合并
(x.sum1 ? x.seml0 : x.sum0 +y.seml0), (y.sum0 ? y.semr0 :y.sum0 + x.semr0),
//更新最大区间
max({x.Mxsem1, y.Mxsem1, x.semr1 + y.seml1}), max({y.Mxsem0, y.Mxsem0, x.semr0 +y.seml0})
);
}
void up(int p) {
tr[p].change(
//计数
tr[lp].sum1+tr[rp].sum1, tr[lp].sum0+tr[rp].sum0,
// 区间1合并
(tr[lp].sum0 ? tr[lp].seml1 : tr[lp].sum1 +tr[rp].seml1), (tr[rp].sum0 ? tr[rp].semr1 :tr[rp].sum1 + tr[lp].semr1),
// 区间0合并
(tr[lp].sum1 ? tr[lp].seml0 : tr[lp].sum0 +tr[rp].seml0), (tr[rp].sum0 ? tr[rp].semr0 :tr[rp].sum0 + tr[lp].semr0),
//更新最大区间
max({tr[lp].Mxsem1, tr[rp].Mxsem1, tr[lp].semr1 + tr[rp].seml1}), max({tr[rp].Mxsem0, tr[rp].Mxsem0, tr[lp].semr0 +tr[rp].seml0})
);
}
//树上节点更新
void update(int typ, int p) {
if (typ == 0)
tr[p].tag2=0, tr[p].tag1=0, tr[p].change(0, tr[p].len(), 0, 0, tr[p].len(), tr[p].len(), 0, tr[p].len());
if (typ == 1)
tr[p].tag2=0, tr[p].tag1=1, tr[p].change(tr[p].len(), 0, tr[p].len(), tr[p].len(), 0, 0, tr[p].len(), 0);
if (typ == 2)
tr[p].tag2 ^= 1, swap(tr[p].sum1, tr[p].sum0), swap(tr[p].Mxsem0, tr[p].Mxsem1),
swap(tr[p].seml1, tr[p].seml0), swap(tr[p].semr0, tr[p].semr1);
}
//标记下传
void down(int p) {
if (tr[p].tag1 != -1) update(tr[p].tag1, lp), update(tr[p].tag1, rp);
if (tr[p].tag2) update(2, lp), update(2, rp);
tr[p].tag1 = -1, tr[p].tag2 = 0;
}
//构建
void build(int l = 0, int r = n-1, int p =1) {
tr[p].l = l, tr[p].r = r;
if (l == r ) {
tr[p].
change(arr[l], arr[l]^1, arr[l], arr[l], arr[l]^1, arr[l]^1, arr[l], arr[l]^1);
return;
}
int mid = l + r >> 1;
build(l, mid, lp);
build(mid+1, r, rp);
up(p);
}
void outtree(int p = 1) {
if (tr[p].l == -1) return;
outtree(lp);
if (tr[p].l == tr[p].r) cout<<tr[p].sum1<<" ";
outtree(rp);
}
//修改
void fix(int l, int r, int typ, int p = 1) {
if (l <= tr[p].l &&tr[p].r <= r) {
update(typ, p);
return;
}
down(p);
if (l <= tr[p].mid()) fix(l, r, typ, lp);
if (r > tr[p].mid()) fix(l, r, typ, rp);
up(p);
}
node query(int l, int r, int p =1) {
if (l <= tr[p].l && tr[p].r <= r) return tr[p];
down(p);
node sum = node();
if (l <= tr[p].mid()) sum = query(l, r, lp);
if (r > tr[p].mid()) merge(sum, query(l, r ,rp));
return sum;
}
int op, l, r;
int main(){
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
cin>>n>>m;
for (int i=0; i<n; i++) cin>>arr[i];
build();
while(m--) {
cin>>op>>l>>r;
if (op < 3)
fix(l, r, op);
else {
node ans = query(l, r); cout<<(op==3 ? ans.sum1 : ans.Mxsem1)<<"\n";
}
}
}