#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
#define left L,m,rt<<1
#define right m+1,R,rt<<1|1
#define maxn 100010
struct node
{
int l1,l0;
int r1,r0;
int m1,m0;
int flag;
int l,r;
}sum[maxn<<2];
int num[100010];
void up(int rt)
{
sum[rt].l0=sum[rt<<1].l0;
sum[rt].r0=sum[rt<<1|1].r0;
sum[rt].l1=sum[rt<<1].l1;
sum[rt].r1=sum[rt<<1|1].r1;
sum[rt].m0=max(sum[rt<<1].m0,sum[rt<<1|1].m0);
sum[rt].m0=max(sum[rt].m0,sum[rt<<1].r0+sum[rt<<1|1].l0);
sum[rt].m1=max(sum[rt<<1].m1,sum[rt<<1|1].m1);
sum[rt].m1=max(sum[rt].m1,sum[rt<<1].r1+sum[rt<<1|1].l1);
if(sum[rt].l0==sum[rt<<1].r-sum[rt<<1].l+1)
sum[rt].l0+=sum[rt<<1|1].l0;
if(sum[rt].r0==sum[rt<<1|1].r-sum[rt<<1|1].l+1)
sum[rt].r0+=sum[rt<<1].r0;
if(sum[rt].l1==sum[rt<<1].r-sum[rt<<1].l+1)
sum[rt].l1+=sum[rt<<1|1].l1;
if(sum[rt].r1==sum[rt<<1|1].r-sum[rt<<1|1].l+1)
sum[rt].r1+=sum[rt<<1].r1;
}
void build(int L,int R,int rt)
{
sum[rt].flag=0;
sum[rt].l=L;
sum[rt].r=R;
if(L==R)
{
if(num[L]==1)
{
sum[rt].r0=sum[rt].l0=sum[rt].m0=0;
sum[rt].r1=sum[rt].l1=sum[rt].m1=1;
}
if(num[L]==0)
{
sum[rt].r0=sum[rt].l0=sum[rt].m0=1;
sum[rt].r1=sum[rt].l1=sum[rt].m1=0;
}
return;
}
int m=(L+R)/2;
build(left);
build(right);
up(rt);
}
void Down(int rt)
{
if(sum[rt].flag)
{
sum[rt<<1].flag^=1;
sum[rt<<1|1].flag^=1;
swap(sum[rt<<1].l0,sum[rt<<1].l1);
swap(sum[rt<<1].r0,sum[rt<<1].r1);
swap(sum[rt<<1].m0,sum[rt<<1].m1);
swap(sum[rt<<1|1].l0,sum[rt<<1|1].l1);
swap(sum[rt<<1|1].r0,sum[rt<<1|1].r1);
swap(sum[rt<<1|1].m0,sum[rt<<1|1].m1);
sum[rt].flag=0;
}
}
void update(int rt,int a,int b)
{
if(a<=sum[rt].l&&b>=sum[rt].r)
{
swap(sum[rt].l0,sum[rt].l1);
swap(sum[rt].r0,sum[rt].r1);
swap(sum[rt].m0,sum[rt].m1);
sum[rt].flag^=1;
return;
}
Down(rt);
int m=(sum[rt].l+sum[rt].r)/2;
if(a<=m)
{
update(rt<<1,a,b);
}
if(b>m)
update(rt<<1|1,a,b);
up(rt);
}
int GetSum(int rt,int a,int b)
{
if(sum[rt].l==a&&sum[rt].r==b)
return sum[rt].m1;
int m=(sum[rt].l+sum[rt].r)/2;
Down(rt);
if(b<=m)
return GetSum(rt<<1,a,b);
else if(a>m) return GetSum(rt<<1|1,a,b);
else
{
int lmax=0,mmax=0,rmax=0;
mmax=min(m-a+1,sum[rt<<1].r1)+min(b-m,sum[rt<<1|1].l1);
lmax=GetSum(rt<<1,a,m);
rmax=GetSum(rt<<1|1,m+1,b);
return max(lmax,max(mmax,rmax));
}
}
int main()
{
int n,i,j,x,a,b,M;
while(~scanf("%d",&n))
{
for(i=1;i<=n;i++)
{
scanf("%d",&num[i]);
}
build(1,n,1);
scanf("%d",&M);
for(i=1;i<=M;i++)
{
scanf("%d %d %d",&x,&a,&b);
if(x==1)
{
update(1,a,b);
}
else
printf("%d\n",GetSum(1,a,b));
}
}
return 0;
}
线段树成段更新+延迟标记法-杭电3911
最新推荐文章于 2021-08-22 23:06:23 发布