第一次学习线段树的时候写的第一道题,想一想那时候天真的自己还是搞了一整天,用了将近标程2倍的代码量,记得那时候当屏幕出现ac是激动的样子,哎,人老了
#include<cstdio>
#include<cstring>
#include<iostream>
#define maxn 100010
#define lson u<<1,l,mid
#define rson u<<1|1,mid+1,r
using namespace std;
int n,m,k;
struct node{
int l,r,s,l1,r1,l0,r0,add,one,zero,vis;//one表示最多有多少个连续的1 zero表示最多有多少个连续的0
}nod[maxn*14];
void swap2(int *a, int *b){
int temp;
temp = *a;
*a = *b;
*b = temp;
}
void pushdown(int u){
int add=nod[u].add;
int l=u<<1;
int r=u<<1|1;
if(add==1){
nod[l].add=nod[r].add=1;
nod[l].s=nod[r].s=0;
nod[l].one=nod[l].l1=nod[l].r1=0;
nod[r].one=nod[r].l1=nod[r].r1=0;
nod[l].zero=nod[l].l0=nod[l].r0=nod[l].r-nod[l].l+1;
nod[r].zero=nod[r].l0=nod[r].r0=nod[r].r-nod[r].l+1;
}
if(add==2){
nod[l].add=nod[r].add=2;
nod[l].s=nod[l].r-nod[l].l+1;
nod[r].s=nod[r].r-nod[r].l+1;
nod[l].zero=nod[l].l0=nod[l].r0=0;
nod[r].zero=nod[r].l0=nod[r].r0=0;
nod[l].one=nod[l].l1=nod[l].r1=nod[l].r-nod[l].l+1;
nod[r].one=nod[r].l1=nod[r].r1=nod[r].r-nod[r].l+1;
}
if(add==3){
bool ok1=1,ok2=1;
if(nod[l].add==1||nod[l].add==2&&nod[l].vis!=-1){
pushdown(l);
}
if(nod[r].add==1||nod[r].add==2&&nod[r].vis!=-1){
pushdown(r);
}
if(nod[l].add==3){
nod[l].add=0;ok1=0;
}
if(nod[r].add==3){
nod[r].add=0;ok2=0;
}
if(ok1)nod[l].add=3;
if(ok2)nod[r].add=3;
nod[l].s=nod[l].r-nod[l].l+1-nod[l].s;
nod[r].s=nod[r].r-nod[r].l+1-nod[r].s;
swap2(&nod[l].l0,&nod[l].l1);
swap2(&nod[l].r0,&nod[l].r1);
swap2(&nod[l].one,&nod[l].zero);
swap2(&nod[r].l0,&nod[r].l1);
swap2(&nod[r].r0,&nod[r].r1);
swap2(&nod[r].one,&nod[r].zero);
}
nod[u].add=0;
}
void pushup(int u){
if(nod[u].add)pushdown(u);
nod[u].s=nod[u<<1].s+nod[u<<1|1].s;
nod[u].zero=max(max(nod[u<<1].zero,nod[u<<1|1].zero),nod[u<<1].r0+nod[u<<1|1].l0);
nod[u].one=max(max(nod[u<<1].one,nod[u<<1|1].one),nod[u<<1].r1+nod[u<<1|1].l1);
int llen=nod[u<<1].r-nod[u<<1].l +1;
int rlen=nod[u<<1|1].r-nod[u<<1|1].l +1;
int l=u<<1;
int r=u<<1|1;
if(nod[l].l1==llen){
nod[u].l1=nod[l].l1 +nod[r].l1;
}
if(nod[r].r1==rlen){
nod[u].r1=nod[r].r1 +nod[l].r1;
}
if(nod[l].l1!=llen){
nod[u].l1 =nod[l].l1;
}
if(nod[r].r1!=rlen){
nod[u].r1 =nod[r].r1;
}
if(nod[l].l0==llen){
nod[u].l0=nod[l].l0 +nod[r].l0;
}
if(nod[r].r0==rlen){
nod[u].r0=nod[r].r0 +nod[l].r0;
}
if(nod[l].l0!=llen){
nod[u].l0 =nod[l].l0;
}
if(nod[r].r0!=rlen){
nod[u].r0 =nod[r].r0;
}
}
void build(int u,int l,int r){
nod[u].l=l,nod[u].r=r;
if(l==r){
int x;
scanf("%d",&x);
nod[u].vis=-1;
nod[u<<1|1].add=-1;
nod[u].s=x;
if(x==1){
nod[u].one=1;
nod[u].zero=0;
nod[u].l1=1;
nod[u].r1=1;
nod[u].l0=0;
nod[u].r0=0;
}
else{
nod[u].one=0;
nod[u].zero=1;
nod[u].l1=0;
nod[u].r1=0;
nod[u].l0=1;
nod[u].r0=1;
}
return;
}
int mid=(l+r)>>1;
build(lson);
build(rson);
pushup(u);
}
void update(int u,int l,int r ,int x,int y,int add){
if(nod[u].add)pushdown(u);
if(l==x&&r==y){
if(add==0){
nod[u].add=1;
nod[u].s=0;
nod[u].one=nod[u].l1=nod[u].r1=0;
nod[u].zero=nod[u].l0=nod[u].r0=nod[u].r-nod[u].l+1;
}
if(add==1){
nod[u].add=2;
nod[u].s=nod[u].r-nod[u].l+1;
nod[u].one=nod[u].l1=nod[u].r1=nod[u].r-nod[u].l+1;
nod[u].zero=nod[u].l0=nod[u].r0=0;
}
if(add==2){
nod[u].add=3;
nod[u].s=nod[u].r-nod[u].l+1-nod[u].s;
swap2(&nod[u].l0,&nod[u].l1);
swap2(&nod[u].r0,&nod[u].r1);
swap2(&nod[u].one,&nod[u].zero);
}
return;
}
int mid=(l+r)>>1;
if(x>mid)update(rson,x,y,add);
else if(y<=mid)update(lson,x,y,add);
else{
update(lson,x,mid,add);
update(rson,mid+1,y,add);
}
pushup(u);
}
int query1(int u,int l,int r,int x,int y){
if(x==l&&y==r){
return nod[u].s;
}
if(nod[u].add)pushdown(u);
int mid=(l+r)>>1;
if(x>mid)return query1(rson,x,y);
else if(y<=mid)return query1(lson,x,y);
else return query1(lson,x,mid)+query1(rson,mid+1,y);
}
int query(int u,int a,int b,int ok){
if(ok){//左
if(nod[u].r-nod[u].r1<a){
return b-a+1;
}
else return nod[u].r1;
}
else{
if(nod[u].l1+a>b)return b-a+1;
else return nod[u].l1;
}
}
int query2(int u,int l,int r,int x,int y){
if(x==l&&r==y){
return nod[u].one;
}
if(nod[u].add)pushdown(u);
int mid=(l+r)>>1;
if(x>mid)return query2(rson,x,y);
else if(y<=mid)return query2(lson,x,y);
else {
return max(max(query2(lson,x,mid),query2(rson,mid+1,y)),query(u<<1,x,mid,1)+query(u<<1|1,mid+1,y,0));
}
}
int main()
{
scanf("%d%d",&n,&m);
build(1,1,n);
while(m--){
int x,a,b;
scanf("%d%d%d",&x,&a,&b);
a++;
b++;
if(x==0)update(1,1,n,a,b,x);
if(x==1)update(1,1,n,a,b,x);
if(x==2)update(1,1,n,a,b,x);
if(x==3){
printf("%d\n",query1(1,1,n,a,b));
}
if(x==4)printf("%d\n",query2(1,1,n,a,b));
}
return 0;
}