题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3911
题意:给出一段边续的01序列,有两种操作,1)更改a,b之间的元素状态;2)查询a,b之间最长的连续的1的长度
线段树题目,维护了六个域来记录该节点的状态,另外要用到Lazy提速
Code:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define M 102220
#define L(x) (x<<1)
#define R(x) (x<<1|1)
#define Mid(x,y) ((x+y)>>1)
#define Swap(x,y,tmp) (tmp=x,x=y,y=tmp)
typedef struct{
int lt,rt;
int maxw,maxb;
int lw,lb,rw,rb;
int c;
}SegT;
SegT T[M*5];
int a[M];
int Max(int a,int b)
{
return a>b?a:b;
}
void Cal(int i)
{
int lt,rt;
lt=L(i);rt=R(i);
T[i].maxw=Max(T[lt].maxw,T[rt].maxw);
T[i].maxb=Max(T[lt].maxb,T[rt].maxb);
T[i].maxw=Max(T[i].maxw,T[lt].rw+T[rt].lw);
T[i].maxb=Max(T[i].maxb,T[lt].rb+T[rt].lb);
T[i].lw=(T[lt].rt-T[lt].lt+1==T[lt].lw)?T[lt].lw+T[rt].lw:T[lt].lw;
T[i].lb=(T[lt].rt-T[lt].lt+1==T[lt].lb)?T[lt].lb+T[rt].lb:T[lt].lb;
T[i].rw=(T[rt].rw==T[rt].rt-T[rt].lt+1)?T[rt].rw+T[lt].rw:T[rt].rw;
T[i].rb=(T[rt].rb==T[rt].rt-T[rt].lt+1)?T[rt].rb+T[lt].rb:T[rt].rb;
}
void Lazy(int i)
{
int lt,rt,tmp;
if(T[i].lt!=T[i].rt){
lt=L(i),rt=R(i);
T[lt].c+=T[i].c;T[rt].c+=T[i].c;
if(T[i].c&1){
Swap(T[lt].maxw,T[lt].maxb,tmp);
Swap(T[rt].maxw,T[rt].maxb,tmp);
Swap(T[lt].lw,T[lt].lb,tmp);
Swap(T[lt].rw,T[lt].rb,tmp);
Swap(T[rt].lw,T[rt].lb,tmp);
Swap(T[rt].rw,T[rt].rb,tmp);
}
}
T[i].c=0;
}
void Create(int i,int l,int r)
{
int mid;
T[i].lt=l;T[i].rt=r;
T[i].c=0;
if(l==r){
T[i].lw=T[i].rw=T[i].maxw=a[l];
T[i].lb=T[i].rb=T[i].maxb=1-a[l];
return ;
}
mid=Mid(l,r);
Create(L(i),l,mid);
Create(R(i),mid+1,r);
Cal(i);
}
void Updata(int i,int l,int r)
{
int mid,tmp;
Lazy(i);
if(T[i].lt>=l&&T[i].rt<=r){
T[i].c++;
Swap(T[i].maxb,T[i].maxw,tmp);
Swap(T[i].lb,T[i].lw,tmp);
Swap(T[i].rb,T[i].rw,tmp);
return ;
}
mid=Mid(T[i].lt,T[i].rt);
if(r<=mid) Updata(L(i),l,r);
else if(l>mid) Updata(R(i),l,r);
else{
Updata(L(i),l,r);
Updata(R(i),l,r);
}
Cal(i);
}
int Query(int i,int l,int r)
{
int ret=0,mid,r1,r2,tmp;
Lazy(i);
if(T[i].lt>=l&&T[i].rt<=r)
return T[i].maxw;
mid=Mid(T[i].lt,T[i].rt);
if(r<=mid) return Query(L(i),l,r);
if(l>mid) return Query(R(i),l,r);
r1=Query(L(i),l,r);
r2=Query(R(i),l,r);
ret=Max(r1,r2);
tmp=T[L(i)].rw+T[R(i)].lw;
if(mid-l+1<T[L(i)].rw)
tmp-=T[L(i)].rw-mid+l-1;
if(r-mid<T[R(i)].lw)
tmp-=T[R(i)].lw-r+mid;
ret=Max(ret,tmp);
return ret;
}
int main()
{
int n,m,i;
int x,f,t;
while(~scanf("%d",&n)){
for(i=1;i<=n;i++)
scanf("%d",a+i);
Create(1,1,n);
scanf("%d",&m);
while(m--){
scanf("%d%d%d",&x,&f,&t);
switch(x){
case 0:printf("%d\n",Query(1,f,t));break;
case 1:Updata(1,f,t);break;
}
}
}
return 1;
}