​题目传送门​​​ 线段树区间合并
一个区间存该区间最长的连续正面朝上的硬币情况和最长的连续反面朝上的硬币情况,如果这个区间全部翻转,交换该区间的这两种情况即可,其他的细节处理就是线段树的区间合并了,延迟标记不要丢掉了
具体看代码吧,感觉写的有点乱,也不想改了

#include<bits/stdc++.h>
using namespace std;

#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
#define ls rt<<1
#define rs rt<<1|1
const int maxn=100000+100;
const int INF=0x3f3f3f3f;

struct Tree{

int lm,mm,rm;
int Lm,Mm,Rm;
int s;
int S;
int l,r;
int lv,rv;
int add;
}tree[maxn<<2];
int ans[maxn];

inline Tree merge(Tree l,Tree r){

Tree fa;
fa.mm=max(l.mm,r.mm);
fa.Mm=max(l.Mm,r.Mm);
fa.lm=l.lm;fa.rm=r.rm;
fa.Lm=l.Lm;fa.Rm=r.Rm;
fa.l=l.l;fa.r=r.r;
fa.lv=l.lv;fa.rv=r.rv;
fa.s=fa.S=-INF;
if(l.rv && r.lv){

fa.mm=max(fa.mm,l.rm+r.lm);
fa.lm=max(fa.lm,l.s+r.lm);
fa.rm=max(fa.rm,l.rm+r.s);
fa.s=max(fa.s,l.s+r.s);
}
if(!l.rv && !r.lv){

fa.Mm=max(fa.Mm,l.Rm+r.Lm);
fa.Lm=max(fa.Lm,l.S+r.Lm);
fa.Rm=max(fa.Rm,l.Rm+r.S);
fa.S=max(fa.S,l.S+r.S);
}
return fa;
}

void build(int rt,int l,int r){

if(l==r){

tree[rt].mm=tree[rt].lm=tree[rt].rm=tree[rt].s=ans[l];
tree[rt].Mm=tree[rt].Lm=tree[rt].Rm=tree[rt].S=(!ans[l]);
tree[rt].l=l;tree[rt].r=r;
tree[rt].add=0;
tree[rt].lv=ans[l];
tree[rt].rv=ans[r];
return ;
}

int mid=(l+r)>>1;
build(lson);
build(rson);
tree[rt]=merge(tree[ls],tree[rs]);tree[rt].add=0;
}

inline void updateup(int rt){

tree[ls].add++;tree[ls].add%=2;
tree[rs].add++;tree[rs].add%=2;
tree[ls].lv++;tree[ls].lv%=2;tree[ls].rv++;tree[ls].rv%=2;
tree[rs].lv++;tree[rs].lv%=2;tree[rs].rv++;tree[rs].rv%=2;
swap(tree[ls].lm,tree[ls].Lm);swap(tree[ls].rm,tree[ls].Rm);
swap(tree[ls].mm,tree[ls].Mm);swap(tree[ls].s,tree[ls].S);
swap(tree[rs].lm,tree[rs].Lm);swap(tree[rs].rm,tree[rs].Rm);
swap(tree[rs].mm,tree[rs].Mm);swap(tree[rs].s,tree[rs].S);
tree[rt].add=0;
}

inline void update(int rt,int l,int r,int L,int R){

if(L>r || R<l) return ;
if(L<=l && R>=r){

tree[rt].add++;tree[rt].add%=2;
tree[rt].lv++;tree[rt].lv%=2;
tree[rt].rv++;tree[rt].rv%=2;
swap(tree[rt].lm,tree[rt].Lm);
swap(tree[rt].rm,tree[rt].Rm);
swap(tree[rt].mm,tree[rt].Mm);
swap(tree[rt].s,tree[rt].S);
return ;
}
if(tree[rt].add) updateup(rt);
int mid=(l+r)>>1;
update(lson,L,R);
update(rson,L,R);
int tmp=tree[rt].add;
tree[rt]=merge(tree[ls],tree[rs]);tree[rt].add=tmp;
}

inline Tree query(int rt,int l,int r,int L,int R){

if(L<=l && R>=r) return tree[rt];
if(tree[rt].add) updateup(rt);
int mid=(l+r)>>1;
if(R<=mid) return query(lson,L,R);
else if(L>mid) return query(rson,L,R);
else return merge(query(lson,L,R),query(rson,L,R));
}

int main(){

int n;
while(scanf("%d",&n)==1){

for(int i=1;i<=n;i++) scanf("%d",&ans[i]);
build(1,1,n);
int m;
scanf("%d",&m);
while(m--){

int type,l,r;
scanf("%d%d%d",&type,&l,&r);
if(type) update(1,1,n,l,r);
else printf("%d\n",query(1,1,n,l,r).mm);
}
}
}