线段树+细节。
主要思路都是正确的,但是细节,,细节,,
区间覆盖要把翻转标记清空!!!
CODE:
#include<cstdio>
#define N 100005
struct tree
{
int num,num0,num1,left0,left1,right0,right1,max0,max1;
bool set0,set1,swap;
inline void swp(int &a,int &b){a^=b,b^=a,a^=b;}
inline void set(int wh,int cnt)
{
num=wh;
num0=left0=right0=max0=!wh?cnt:0;
num1=left1=right1=max1=wh?cnt:0;
set0=!wh?1:0,set1=wh?1:0;
swap=0;
}
inline void Swap()
{
num^=1;
swp(num0,num1);
swp(left0,left1);
swp(right0,right1);
swp(max0,max1);
swap^=1;
}
}t[N<<2];
int n,m,opt,x,y;
inline int max(const int &a,const int &b){return a>b?a:b;}
inline int min(const int &a,const int &b){return a<b?a:b;}
inline void pushdown(int l,int r,int now)
{
if(!t[now].set0&&!t[now].set1&&!t[now].swap) return;
int mid=(l+r)>>1,s1=now<<1,s2=now<<1|1;
if(t[now].set0) t[s1].set(0,mid-l+1),t[s2].set(0,r-mid),t[now].set0=0;
if(t[now].set1) t[s1].set(1,mid-l+1),t[s2].set(1,r-mid),t[now].set1=0;
if(t[now].swap) t[s1].Swap(),t[s2].Swap(),t[now].swap=0;
}
inline void update(int l,int r,int now)
{
int mid=(l+r)>>1,s1=now<<1,s2=now<<1|1;
t[now].left0=t[s1].left0;
if(t[s1].left0==mid-l+1) t[now].left0+=t[s2].left0;
t[now].left1=t[s1].left1;
if(t[s1].left1==mid-l+1) t[now].left1+=t[s2].left1;
t[now].num0=t[s1].num0+t[s2].num0;
t[now].num1=t[s1].num1+t[s2].num1;
t[now].right0=t[s2].right0;
if(t[s2].right0==r-mid) t[now].right0+=t[s1].right0;
t[now].right1=t[s2].right1;
if(t[s2].right1==r-mid) t[now].right1+=t[s1].right1;
t[now].max0=max(t[s1].right0+t[s2].left0,max(max(t[s1].max0,t[s2].max0),max(t[now].left0,t[now].right0)));
t[now].max1=max(t[s1].right1+t[s2].left1,max(max(t[s1].max1,t[s2].max1),max(t[now].left1,t[now].right1)));
}
void build(int l,int r,int now)
{
if(l==r)
{
int tmp;
scanf("%d",&tmp);
t[now].set(tmp,1);
return;
}
int mid=(l+r)>>1;
build(l,mid,now<<1);
build(mid+1,r,now<<1|1);
update(l,r,now);
}
void change(int L,int R,int l,int r,int now,int num)
{
if(L<=l&&r<=R) return t[now].set(num,r-l+1);
int mid=(l+r)>>1;
pushdown(l,r,now);
if(L<=mid) change(L,R,l,mid,now<<1,num);
if(R>mid) change(L,R,mid+1,r,now<<1|1,num);
update(l,r,now);
}
void swap(int L,int R,int l,int r,int now)
{
if(L<=l&&r<=R) return t[now].Swap();
int mid=(l+r)>>1;
pushdown(l,r,now);
if(L<=mid) swap(L,R,l,mid,now<<1);
if(R>mid) swap(L,R,mid+1,r,now<<1|1);
update(l,r,now);
}
int ask(int L,int R,int l,int r,int now)
{
if(L<=l&&r<=R) return t[now].num1;
int mid=(l+r)>>1,ans=0;
pushdown(l,r,now);
if(L<=mid) ans=ask(L,R,l,mid,now<<1);
if(R>mid) ans+=ask(L,R,mid+1,r,now<<1|1);
return ans;
}
tree askmax(int L,int R,int l,int r,int now)
{
if(L<=l&&r<=R) return t[now];
int mid=(l+r)>>1;
pushdown(l,r,now);
if(R<=mid) return askmax(L,R,l,mid,now<<1);
if(L>mid) return askmax(L,R,mid+1,r,now<<1|1);
tree tmp1,tmp2,ans;
tmp1=askmax(L,R,l,mid,now<<1);
tmp2=askmax(L,R,mid+1,r,now<<1|1);
ans.left1=tmp1.left1;
if(tmp1.left1==mid-max(L,l)+1) ans.left1+=tmp2.left1;
ans.right1=tmp2.right1;
if(tmp2.right1==min(r,R)-mid) ans.right1+=tmp1.right1;
ans.max1=max(tmp1.right1+tmp2.left1,max(max(tmp1.max1,tmp2.max1),max(ans.left1,ans.right1)));
return ans;
}
int main()
{
scanf("%d%d",&n,&m);
build(1,n,1);
while(m--)
{
scanf("%d%d%d",&opt,&x,&y),x++,y++;
if(!opt) change(x,y,1,n,1,0);
else if(opt==1) change(x,y,1,n,1,1);
else if(opt==2) swap(x,y,1,n,1);
else if(opt==3) printf("%d\n",ask(x,y,1,n,1));
else printf("%d\n",askmax(x,y,1,n,1).max1);
}
return 0;
}