代码写得比较乱。
区间最长连续黑色:maxb
区间最长连续白色:maxw
区间左端点颜色: lcolor
区间右端点颜色:rcolor
左端点起最长连续数:lmax
右端点起最长连续数:rmax
标记区间是否被更改过:flag
#include<iostream>
using namespace std;
struct tree
{
int left;
int right;
int maxb,maxw;
int lcolor,rcolor;
int lmax,rmax;
int flag;
}t[400000];
inline int max(int a,int b)
{
return a>b? a:b;
}
inline int min(int a,int b)
{
return a>b? b:a;
}
int key[100005];
void create(int l,int r,int now);
void add_node(int now);
void update_node(int now);
void update_tree(int l,int r,int now);
void change_node(int now);
int query(int l,int r,int now);
int main()
{
int n,m,x,l,r,ans;
while(scanf("%d",&n)!=EOF)
{
for(int i=1;i<=n;i++)
{
scanf("%d",&key[i]);
}
create(1,n,1);
add_node(1);
cin>>m;
while(m--)
{
scanf("%d%d%d",&x,&l,&r);
if(x==0)
{
ans=query(l,r,1);
printf("%d\n",ans);
}
else
update_tree(l,r,1);
}
}
return 0;
}
void create(int l,int r,int now)
{
t[now].left=l;
t[now].right=r;
t[now].lmax=0;
t[now].rmax=0;
t[now].maxb=0;
t[now].maxw=0;
t[now].rcolor=0;
t[now].lcolor=0;
t[now].flag=0;
if(l<r)
{
int mid=(r+l)>>1;
create(l,mid,now<<1);
create(mid+1,r,(now<<1)+1);
}
return;
}
void add_node(int now)
{
if(t[now].left==t[now].right)
{
t[now].lcolor=t[now].rcolor=key[t[now].left];
t[now].lmax=t[now].rmax=1;
t[now].maxb=key[t[now].left];
t[now].maxw=1-key[t[now].left];
t[now].flag=0;
return ;
}
add_node(now<<1);
add_node( (now<<1)+1 );
update_node(now);
return ;
}
void update_node(int now)
{
int left=now<<1,right=(now<<1)+1;
t[now].lcolor=t[left].lcolor;
t[now].rcolor=t[right].rcolor;
if(t[left].lmax==t[left].right-t[left].left+1 && t[left].rcolor==t[right].lcolor)
t[now].lmax=t[left].lmax+t[right].lmax;
else
t[now].lmax=t[left].lmax;
if(t[right].rmax==t[right].right-t[right].left+1 && t[right].lcolor==t[left].rcolor)
t[now].rmax=t[right].rmax+t[left].rmax;
else
t[now].rmax=t[right].rmax;
t[now].maxb=max(t[right].maxb,t[left].maxb);
t[now].maxw=max(t[right].maxw,t[left].maxw);
if(t[left].rcolor==t[right].lcolor)
{
if(t[left].rcolor==1)
t[now].maxb=max(t[now].maxb,t[left].rmax+t[right].lmax);
else if(t[left].rcolor==0)
t[now].maxw=max(t[now].maxw,t[left].rmax+t[right].lmax);
}
}
void update_tree(int l,int r,int now)
{
if(t[now].left==l && t[now].right==r)
{
change_node(now);
return ;
}
if(t[now].flag==1)
{
change_node(now<<1);
change_node( (now<<1) +1);
t[now].flag=0;
}
int mid=(t[now].left+t[now].right)>>1;
if(r<=mid)
update_tree(l,r,now<<1);
else if(l>mid)
update_tree(l,r,(now<<1)+1);
else
{
update_tree(l,mid,now<<1);
update_tree(mid+1,r,(now<<1)+1);
}
update_node(now);
}
void change_node(int now)
{
t[now].lcolor=t[now].lcolor^1;
t[now].rcolor=t[now].rcolor^1;
t[now].maxb=t[now].maxb^t[now].maxw;
t[now].maxw=t[now].maxb^t[now].maxw;
t[now].maxb=t[now].maxb^t[now].maxw;
t[now].flag=t[now].flag^1;
}
int query(int l,int r,int now)
{
if(t[now].left==l && t[now].right==r)
return t[now].maxb;
if(t[now].flag==1)
{
change_node(now<<1);
change_node( (now<<1)+1 );
t[now].flag=0;
}
int mid=(t[now].left+t[now].right)>>1;
// int left=now<<1,right=(now<<1)+1;
int t1=0,t2=0,t3=0,t4=0,t5=0;
if(r<=mid)
t1=query(l,r,now<<1);
else if(l>mid)
t2=query(l,r,(now<<1)+1);
else
{
t3=query(l,mid,now<<1);
t4=query(mid+1,r,(now<<1)+1);
if(t[now<<1].rcolor==1 && t[ (now<<1)+1 ].lcolor==1)
t5=min(mid-l+1,t[now<<1].rmax)+min(r-mid,t[ (now<<1)+1].lmax);
}
update_node(now);
return max( max( max(t1,t2),max(t3,t4) ) , t5);
}