不知道哪出问题了,自己尝试无果只能找大佬捞捞了P2572
#include <bits/stdc++.h>
#define int long long
#define lson id<<1,l,mid
#define rson id<<1|1,mid+1,r
#define ls id<<1
#define rs id<<1|1
using namespace std;
const int XB=1145141919810;//莫名恶臭
const int AC=2e5;
int n,m;
struct st{
int l,r;//区间左右边界
int cover,add;//覆盖懒标记 取反懒标记
int zero,one;//零的个数 一的个数
int mz,mo,lmz,lmo,rmz,rmo;//区间最长0、1长度 lmx: l->r 最长0、1连续长度 rmx:r->l 最长0、1连续长度
/* 抽象图如下↓
l |--------------| r (任意节点)
lmx--> <--rmx
*/
}tree[AC*4];
inline int read(){
int x=0,w=1;
char ch=0;
while (ch<'0'||ch>'9') {if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9') {x=x*10+(ch-'0');ch=getchar();}return x*w;
}
inline void up(int id){//向上更新
//处理1和0的总数
tree[id].zero=tree[ls].zero+tree[rs].zero;
tree[id].one=tree[ls].one+tree[rs].one;
//维护连续1
//处理lmo部分
if(tree[ls].mo==tree[ls].r-tree[ls].l+1){//如果左子树的1全满
tree[id].lmo=tree[ls].mo+tree[rs].lmo;//不要max的原因时因为左子树全满,中间部分已经算在里面了
}
else{//如果左子树的1不满,该节点的从l开始的1为左儿子的lmo
tree[id].lmo=tree[ls].lmo;
}
//处理rmo部分
if(tree[rs].mo==tree[rs].r-tree[rs].l+1){//同理
tree[id].rmo=tree[rs].mo+tree[ls].rmo;
}
else{
tree[id].rmo=tree[rs].rmo;
}
tree[id].mo=max(max(tree[ls].mo,tree[rs].mo),tree[ls].rmo+tree[rs].lmo);
//维护连续0
//处理lmz部分 (原理同上)
if(tree[ls].mz==tree[ls].r-tree[ls].l+1){
tree[id].lmz=tree[ls].mz+tree[rs].lmz;
}
else{
tree[id].lmz=tree[ls].lmz;
}
//处理rmz
if(tree[rs].mz==tree[rs].r-tree[rs].l+1){
tree[id].rmz=tree[rs].mz+tree[ls].rmz;
}
else{
tree[id].rmz=tree[rs].rmz;
}
tree[id].mz=max(max(tree[ls].mz,tree[rs].mz),tree[ls].rmz+tree[rs].lmz);
}
inline void down(int id){
if(tree[id].cover!=XB){
//处理子树的add和cover
tree[ls].cover=tree[id].cover;
tree[rs].cover=tree[id].cover;
tree[ls].add=tree[rs].add=0;
//处理cover
if(tree[id].cover==0){//覆盖0
//左子树
tree[ls].mo=tree[ls].lmo=tree[ls].rmo=tree[ls].one=0;
tree[ls].mz=tree[ls].lmz=tree[ls].rmz=tree[ls].zero=tree[ls].r-tree[ls].l+1;
//右子树
tree[rs].mo=tree[rs].lmo=tree[rs].rmo=tree[rs].one=0;
tree[rs].mz=tree[rs].lmz=tree[rs].rmz=tree[rs].zero=tree[rs].r-tree[rs].l+1;
}
else if(tree[id].cover==1){//覆盖1
//左子树
tree[ls].mz=tree[ls].lmz=tree[ls].rmz=tree[ls].zero=0;
tree[ls].mo=tree[ls].lmo=tree[ls].lmo=tree[ls].one=tree[ls].r-tree[ls].l+1;
//右子树
tree[rs].mz=tree[rs].lmz=tree[rs].rmz=tree[rs].zero=0;
tree[rs].mo=tree[rs].lmo=tree[rs].lmo=tree[rs].one=tree[rs].r-tree[rs].l+1;
}
tree[id].cover=XB;
}
if(tree[id].add){
//处理子树的add
if(tree[ls].cover!=XB) tree[ls].cover^=1;
else tree[ls].add^=1;
if(tree[rs].cover!=XB) tree[rs].cover^=1;
else tree[rs].add^=1;
tree[id].add=0;
//交换0 1
//左边
swap(tree[ls].one,tree[ls].zero);
swap(tree[ls].lmo,tree[ls].lmz);
swap(tree[ls].mo,tree[ls].mz);
swap(tree[ls].rmo,tree[ls].rmz);
//右边
swap(tree[rs].one,tree[rs].zero);
swap(tree[rs].lmo,tree[rs].lmz);
swap(tree[rs].mo,tree[rs].mz);
swap(tree[rs].rmo,tree[rs].rmz);
}
}
inline void build(int id,int l,int r){
tree[id].cover=XB;//避免覆盖时出现错误
tree[id].l=l;tree[id].r=r;
if(l==r){
int sum;
sum=read();
if(sum==0){//当输入为0时
tree[id].zero=1;
tree[id].mz=1;
tree[id].lmz=tree[id].rmz=1;
}
else{//当输入为1时
tree[id].one=1;
tree[id].mo=1;
tree[id].lmo=tree[id].rmo=1;
}
return ;
}
int mid=(l+r)>>1;
build(lson);build(rson);
up(id);
}
inline void update0(int id,int l,int r,int L,int R){//操作0 将[L,R]区间内的数变成0
if(L>r||l>R) return ;
if(L<=l&&r<=R){
//1的改变
tree[id].mo=tree[id].lmo=tree[id].rmo=tree[id].one=0;
//0的改变
tree[id].mz=tree[id].lmz=tree[id].rmz=tree[id].zero=r-l+1;
tree[id].cover=0;
return ;
}
down(id);
int mid=(l+r)>>1;
if(L<=mid) update0(lson,L,R);
if(R>mid) update0(rson,L,R);
up(id);
}
inline void update1(int id,int l,int r,int L,int R){//操作1 将[L,R]区间内的数变成1
if(L>r||l>R) return ;
if(L<=l&&r<=R){
//0的改变
tree[id].mz=tree[id].lmz=tree[id].rmz=tree[id].zero=0;
//1的改变
tree[id].mo=tree[id].lmo=tree[id].lmo=tree[id].one=r-l+1;
tree[id].cover=1;
return ;
}
down(id);
int mid=(l+r)>>1;
if(L<=mid) update1(lson,L,R);
if(R>mid) update1(rson,L,R);
up(id);
}
inline void update2(int id,int l,int r,int L,int R){
if(L>r||l>R) return ;
if(L<=l&&r<=R){
//处理懒标记优先级
if(tree[id].cover!=XB){
tree[id].cover^=1;
}
else{
tree[id].add^=1;
}
//交换0 1
swap(tree[id].lmo,tree[id].lmz);
swap(tree[id].rmo,tree[id].rmz);
swap(tree[id].mo,tree[id].mz);
swap(tree[id].one,tree[id].zero);
return ;
}
down(id);
int mid=(l+r)>>1;
if(L<=mid) update2(lson,L,R);
if(R>mid) update2(rson,L,R);
up(id);
}
inline int query3(int id,int l,int r,int L,int R){
if(L>r||l>R) return 0;
if(L<=l&&r<=R) return tree[id].one;
int mid=(l+r)>>1;
down(id);up(id);
return query3(lson,L,R)+query3(rson,L,R);
}
inline st query4(int id,int l,int r,int L,int R){
int mid=(l+r)>>1;
up(id);down(id);
if(l>=L&&r<=R) return tree[id];
if(mid>=R) return query4(lson,L,R);
else if(mid<L) return query4(rson,L,R);
else{
st su,a=query4(lson,L,R),b=query4(rson,L,R);
su.one=a.one+b.one;
su.zero=a.zero+b.zero;
if(a.mo==a.one) su.lmo=a.mo+b.lmo;
else su.lmo=a.lmo;
if(b.mo==b.one) su.rmo=b.mo+a.rmo;
else su.rmo=b.rmo;
if(a.mz==a.zero) su.lmz=a.mz+b.lmz;
else su.lmz=a.lmz;
if(b.mz==b.zero) su.rmz=b.mz+a.rmz;
else su.rmz=b.rmz;
su.mo=max(max(a.mo,b.mo),a.rmo+b.lmo);
su.mz=max(max(a.mz,b.mz),a.rmz+b.lmz);
return su;
}
}
inline void sop(int id,int l,int r){
if(l==r){
cout<<tree[id].one<<' ';
return ;
}
up(id);down(id);up(id);
int mid=(l+r)/2;
sop(lson);sop(rson);
}
signed main(){
n=read();m=read();
build(1,1,n);
while(m--){
int op,l,r;
op=read();l=read()+1;r=read()+1;
if(op==0) update0(1,1,n,l,r);
if(op==1) update1(1,1,n,l,r);
if(op==2) update2(1,1,n,l,r);
if(op==3) printf("%lld\n",query3(1,1,n,l,r));
if(op==4) printf("%lld\n",query4(1,1,n,l,r).mo);
// sop(1,1,n);cout<<" "<<tree[1].one<<' '<<tree[1].mo<<endl;
}
}