思路:覆盖标记要有两种 当前段全部是1 当前段全部是0 当然开一个数组写也是可以的
但是!!再覆盖过程中,
要和异或标记分清楚 如果你先覆盖那么后面随便你来几个抑或标记都只要处理异或标记
但是不管当前有什么标记 只要又覆盖标记 其他标记就都没有了
因此在向下更新的过程中 要逆次序进行 也就是先处理是否有覆盖标记 然后再处理抑或标记
#include<iostream>
#include<stdio.h>
#include<cstdio>
using namespace std;
#define ls (rt<<1)
#define rs (rt<<1|1)
#define mid ((l+r)>>1)
#define maxn 222222
int l0[maxn<<2],m0[maxn<<2],r0[maxn<<2];
int l1[maxn<<2],m1[maxn<<2],r1[maxn<<2];
int lazy0[maxn<<2],lazy1[maxn<<2];
int sum[maxn<<2];
int ox[maxn<<2];
int n,m,x,a,b;
void up(int rt,int l,int r)
{
l0[rt]=l0[ls];m0[rt]=max(m0[ls],m0[rs]);r0[rt]=r0[rs];
l1[rt]=l1[ls];m1[rt]=max(m1[ls],m1[rs]);r1[rt]=r1[rs];
if(l0[ls]==(mid-l+1))
l0[rt]+=l0[rs];
if(l1[ls]==(mid-l+1))
l1[rt]+=l1[rs];
if(r0[rs]==(r-mid))
r0[rt]+=r0[ls];
if(r1[rs]==(r-mid))
r1[rt]+=r1[ls];
m0[rt]=max(r0[ls]+l0[rs],m0[rt]);
m1[rt]=max(r1[ls]+l1[rs],m1[rt]);
sum[rt]=sum[ls]+sum[rs];
}
void build(int rt,int l,int r)
{
ox[rt]=lazy0[rt]=lazy1[rt]=-1;
sum[rt]=0;
if(l==r)
{
scanf("%d",&x);
sum[rt]=l1[rt]=r1[rt]=m1[rt]=x;
l0[rt]=r0[rt]=m0[rt]=x^1;
return ;
}
build(ls,l,mid);
build(rs,mid+1,r);
up(rt,l,r);
}
void down(int rt,int l,int r)//0 1 ox
{
if(lazy0[rt]!=-1){
lazy0[ls]=lazy0[rs]=lazy0[rt]; lazy0[rt]=-1;
lazy1[ls]=lazy1[rs]=-1;
ox[ls]=ox[rs]=-1;
sum[ls]=sum[rs]=0;
m0[ls]=l0[ls]=r0[ls]=mid-l+1;
m0[rs]=l0[rs]=r0[rs]=r-mid;
m1[ls]=l1[ls]=r1[ls]=0;
m1[rs]=l1[rs]=r1[rs]=0;
}
if(lazy1[rt]!=-1){
lazy1[ls]=lazy1[rs]=lazy1[rt]; lazy1[rt]=-1;
lazy0[ls]=lazy0[rs]=-1;
ox[ls]=ox[rs]=-1;
sum[ls]=(mid-l+1);
sum[rs]=r-mid;
m1[ls]=r1[ls]=l1[ls]=mid-l+1;
m1[rs]=r1[rs]=l1[rs]=r-mid;
m0[ls]=l0[ls]=r0[ls]=0;
m0[rs]=l0[rs]=r0[rs]=0;
}
if(ox[rt]!=-1)
{
ox[ls]=(ox[ls]==-1?1:-1);
ox[rs]=(ox[rs]==-1?1:-1);
ox[rt]=-1;
swap(l0[ls],l1[ls]);
swap(r0[ls],r1[ls]);
swap(l0[rs],l1[rs]);
swap(r0[rs],r1[rs]);
swap(m0[ls],m1[ls]);
swap(m0[rs],m1[rs]);
sum[ls]=(mid-l+1)-sum[ls];
sum[rs]=(r-mid)-sum[rs];
}
}
void insox(int rt,int l,int r,int L,int R)
{
if(L<=l&&r<=R){
ox[rt]=(ox[rt]==1?-1:1);
swap(l0[rt],l1[rt]);
swap(r0[rt],r1[rt]);
swap(m0[rt],m1[rt]);
sum[rt]=(r-l+1)-sum[rt];
return ;
}
down(rt,l,r);
if(L<=mid)insox(ls,l,mid,L,R);
if(mid<R)insox(rs,mid+1,r,L,R);
up(rt,l,r);
}
void ins0(int rt,int l,int r,int L,int R){
if(L<=l&&r<=R){
m0[rt]=l0[rt]=r0[rt]=(r-l+1);
m1[rt]=l1[rt]=r1[rt]=0;
lazy0[rt]=1;
ox[rt]=-1;
lazy1[rt]=-1;
sum[rt]=0;
return ;
}
down(rt,l,r);
if(L<=mid)ins0(ls,l,mid,L,R);
if(mid<R)ins0(rs,mid+1,r,L,R);
up(rt,l,r);
}
void ins1(int rt,int l,int r,int L,int R){
if(L<=l&&r<=R){
m1[rt]=l1[rt]=r1[rt]=(r-l+1);
m0[rt]=l0[rt]=r0[rt]=0;
ox[rt]=-1;
lazy1[rt]=1;
lazy0[rt]=-1;
sum[rt]=(r-l+1);
return ;
}
down(rt,l,r);
if(L<=mid)ins1(ls,l,mid,L,R);
if(mid<R)ins1(rs,mid+1,r,L,R);
up(rt,l,r);
}
int tmp,tmpl,tmpr;
int querys(int rt,int l,int r,int L,int R){
if(L<=l&&r<=R){
return sum[rt];
}
int ans=0;
down(rt,l,r);
if(L<=mid)ans+=querys(ls,l,mid,L,R);
if(mid<R)ans+=querys(rs,mid+1,r,L,R);
return ans;
}
int query(int rt,int l,int r,int L,int R)
{
if(L<=l&&r<=R)
return m1[rt];
down(rt,l,r);
if(mid>=R)tmp=query(ls,l,mid,L,R);
else if(mid<L)tmp=query(rs,mid+1,r,L,R);
else{
tmp=max(query(ls,l,mid,L,R),query(rs,mid+1,r,L,R));
tmpl=min(mid-L+1,r1[ls]);
tmpr=min(R-mid,l1[rs]);
tmp=max(tmp,tmpl+tmpr);
}
return tmp;
}
void gao()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
build(1,1,n);
while(m--){
scanf("%d%d%d",&x,&a,&b);
a++; b++;
if(x==0){
ins0(1,1,n,a,b);
}
else if(x==1){
ins1(1,1,n,a,b);
}
else if(x==2){
insox(1,1,n,a,b);
}
else if(x==3){
printf("%d\n",querys(1,1,n,a,b));
}
else if(x==4){
printf("%d\n",query(1,1,n,a,b));
}
}
}
}
int main()
{
gao();
return 0;
}