其实这道题没有什么特殊的地方….就是一定不要用cin&cout会RE…
还有就是合并lazy的标记的时候一定要想清楚…(我把-1写成1查了半天…)
代码如下:
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
//by NeighThorn
using namespace std;
const int maxn=100000+5;
int n,m,pri[maxn];
struct Tree{
int l,r,pre0,suf0,seq0,pre1,suf1,seq1,No1,len,lazy;
}tree[maxn*4];
inline void build(int l,int r,int tr){
tree[tr].l=l,tree[tr].r=r;tree[tr].len=tree[tr].r-tree[tr].l+1;tree[tr].lazy=-1;
if(l==r){
if(pri[l]==0)
tree[tr].pre0=1,tree[tr].suf0=1,tree[tr].seq0=1,tree[tr].pre1=tree[tr].suf1=tree[tr].seq1=0,tree[tr].No1=0;
else
tree[tr].pre1=1,tree[tr].suf1=1,tree[tr].seq1=1,tree[tr].pre0=tree[tr].suf0=tree[tr].seq0=0,tree[tr].No1=1;
return;
}
int mid=(l+r)>>1;
build(l,mid,tr<<1),build(mid+1,r,tr<<1|1);
if(tree[tr<<1].pre0==tree[tr<<1].len)
tree[tr].pre0=tree[tr<<1].len+tree[tr<<1|1].pre0;
else
tree[tr].pre0=tree[tr<<1].pre0;
if(tree[tr<<1|1].suf0==tree[tr<<1|1].len)
tree[tr].suf0=tree[tr<<1|1].len+tree[tr<<1].suf0;
else
tree[tr].suf0=tree[tr<<1|1].suf0;
tree[tr].seq0=max(tree[tr<<1].seq0,tree[tr<<1|1].seq0);
tree[tr].seq0=max(tree[tr].seq0,tree[tr<<1].suf0+tree[tr<<1|1].pre0);
if(tree[tr<<1].pre1==tree[tr<<1].len)
tree[tr].pre1=tree[tr<<1].len+tree[tr<<1|1].pre1;
else
tree[tr].pre1=tree[tr<<1].pre1;
if(tree[tr<<1|1].suf1==tree[tr<<1|1].len)
tree[tr].suf1=tree[tr<<1|1].len+tree[tr<<1].suf1;
else
tree[tr].suf1=tree[tr<<1|1].suf1;
tree[tr].seq1=max(tree[tr<<1].seq1,tree[tr<<1|1].seq1);
tree[tr].seq1=max(tree[tr].seq1,tree[tr<<1].suf1+tree[tr<<1|1].pre1);
tree[tr].No1=tree[tr<<1].No1+tree[tr<<1|1].No1;
}
inline void change(int l,int r,int order,int tr){
// cout<<l<<" "<<r<<" "<<tree[tr].l<<" "<<tree[tr].r<<" "<<tree[tr].lazy<<" "<<order<<endl;
if(tree[tr].l==l&&tree[tr].r==r){
if(order==0)
tree[tr].pre0=tree[tr].suf0=tree[tr].seq0=tree[tr].len,
tree[tr].pre1=tree[tr].suf1=tree[tr].seq1=tree[tr].No1=0;
else if(order==1)
tree[tr].pre0=tree[tr].suf0=tree[tr].seq0=0,
tree[tr].pre1=tree[tr].suf1=tree[tr].seq1=tree[tr].No1=tree[tr].len;
else if(order==2)
swap(tree[tr].pre0,tree[tr].pre1),swap(tree[tr].suf0,tree[tr].suf1),swap(tree[tr].seq0,tree[tr].seq1),
tree[tr].No1=tree[tr].len-tree[tr].No1;
if(order!=2)
tree[tr].lazy=order;
else if(tree[tr].lazy==-1)
tree[tr].lazy=order;
else if(tree[tr].lazy!=2)
tree[tr].lazy^=1;
else if(tree[tr].lazy==2)
tree[tr].lazy=-1;
return;
}
int mid=(tree[tr].l+tree[tr].r)>>1;
if(tree[tr].lazy!=-1)
change(tree[tr].l,mid,tree[tr].lazy,tr<<1),change(mid+1,tree[tr].r,tree[tr].lazy,tr<<1|1),tree[tr].lazy=-1;
if(r<=mid)
change(l,r,order,tr<<1);
else if(l>mid)
change(l,r,order,tr<<1|1);
else
change(l,mid,order,tr<<1),change(mid+1,r,order,tr<<1|1);
if(tree[tr<<1].pre0==tree[tr<<1].len)
tree[tr].pre0=tree[tr<<1].len+tree[tr<<1|1].pre0;
else
tree[tr].pre0=tree[tr<<1].pre0;
if(tree[tr<<1|1].suf0==tree[tr<<1|1].len)
tree[tr].suf0=tree[tr<<1|1].len+tree[tr<<1].suf0;
else
tree[tr].suf0=tree[tr<<1|1].suf0;
tree[tr].seq0=max(tree[tr<<1].seq0,tree[tr<<1|1].seq0);
tree[tr].seq0=max(tree[tr].seq0,tree[tr<<1].suf0+tree[tr<<1|1].pre0);
if(tree[tr<<1].pre1==tree[tr<<1].len)
tree[tr].pre1=tree[tr<<1].len+tree[tr<<1|1].pre1;
else
tree[tr].pre1=tree[tr<<1].pre1;
if(tree[tr<<1|1].suf1==tree[tr<<1|1].len)
tree[tr].suf1=tree[tr<<1|1].len+tree[tr<<1].suf1;
else
tree[tr].suf1=tree[tr<<1|1].suf1;
tree[tr].seq1=max(tree[tr<<1].seq1,tree[tr<<1|1].seq1);
tree[tr].seq1=max(tree[tr].seq1,tree[tr<<1].suf1+tree[tr<<1|1].pre1);
tree[tr].No1=tree[tr<<1].No1+tree[tr<<1|1].No1;
}
inline int query(int l,int r,int order,int tr){
if(tree[tr].l==l&&tree[tr].r==r){
if(order==3)
return tree[tr].No1;
else if(order==4)
return tree[tr].seq1;
else if(order==5)
return tree[tr].pre1;
else
return tree[tr].suf1;
}
int mid=(tree[tr].l+tree[tr].r)>>1;
if(tree[tr].lazy!=-1)
change(tree[tr].l,mid,tree[tr].lazy,tr<<1),change(mid+1,tree[tr].r,tree[tr].lazy,tr<<1|1),tree[tr].lazy=-1;
if(r<=mid)
return query(l,r,order,tr<<1);
else if(l>mid)
return query(l,r,order,tr<<1|1);
else{
if(order==3)
return query(l,mid,order,tr<<1)+query(mid+1,r,order,tr<<1|1);
else if(order==4){
int lala=max(query(l,mid,order,tr<<1),query(mid+1,r,order,tr<<1|1));
lala=max(lala,query(l,mid,6,tr<<1)+query(mid+1,r,5,tr<<1|1));
return lala;
}
else if(order==5){
int lala=query(l,mid,order,tr<<1);
if(lala==mid-l+1)
lala+=query(mid+1,r,order,tr<<1|1);
return lala;
}
else{
int lala=query(mid+1,r,order,tr<<1|1);
if(lala==r-mid)
lala+=query(l,mid,order,tr<<1);
return lala;
}
}
}
signed main(void){
// freopen("in.txt","r",stdin);
// freopen("out1.txt","w",stdout);
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%d",&pri[i]);
build(1,n,1);int s,x,y;
while(m--){
scanf("%d%d%d",&s,&x,&y);x++,y++;
if(s>=0&&s<=2)
change(x,y,s,1);//,cout<<"lala"<<query(1,6,3,1)<<" lalala"<<query(1,6,4,1)<<endl;
else
printf("%d\n",query(x,y,s,1));
}
return 0;
}
by >_< NeighThorn