题面:Luogu2572 BZOJ1858
(傻逼)题?
我不会告诉你我写了调了一个晚上才A掉。。。(逃
思路真的挺简(sha)单(bi),其实就是线段树维护区间和,区间最长连续段。
但是细节实在太多。。。代码太难写。。。
首先关于这个标记的问题,覆盖标记的优先级比反转的高,所以我们一旦加上覆盖标记之后,这个节点之前有的标记都可以清除掉了。。。
还有,如果在这个节点加上反转标记的时候,这个节点有覆盖标记,那就把覆盖标记反转即可,这个反转标记就不必下传了。
然后就是一系列的细节问题了。。。比如合并下传之类的难写难调的东西。。。
最后献上4k代码。。。
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <iostream>
#include <ctime>
#include <map>
#include <queue>
#include <cstdlib>
#include <string>
#include <climits>
#include <set>
#include <vector>
using namespace std;
struct tree{
int lt,rt,sum[2],ls[2],rs[2],ss[2],ro,a[2];
inline void pre(){lt=rt=sum[0]=sum[1]=ls[0]=ls[1]=rs[0]=rs[1]=ss[0]=ss[1]=ro=a[0]=a[1]=0;}
}t[400010];
tree operator +(tree a,tree b){
tree c;c.pre();
c.lt=a.lt;c.rt=b.rt;
for(int i=0;i<2;i++){
c.sum[i]=a.sum[i]+b.sum[i];
if(a.ls[i]==a.rt-a.lt+1)c.ls[i]=a.ls[i]+b.ls[i];else c.ls[i]=a.ls[i];
if(b.rs[i]==b.rt-b.lt+1)c.rs[i]=b.rs[i]+a.rs[i];else c.rs[i]=b.rs[i];
c.ss[i]=max(max(a.ss[i],b.ss[i]),a.rs[i]+b.ls[i]);
}
return c;
}
int n,m,a[100010];
inline void jh(int nod){
swap(t[nod].sum[0],t[nod].sum[1]);
swap(t[nod].ls[0],t[nod].ls[1]);
swap(t[nod].rs[0],t[nod].rs[1]);
swap(t[nod].ss[0],t[nod].ss[1]);
}
inline void pushdown(int nod){
if(t[nod].lt==t[nod].rt){t[nod].ro=t[nod].a[0]=t[nod].a[1]=0;return;}
for(int i=0;i<2;i++)if(t[nod].a[i]){
t[nod*2].sum[i]=t[nod*2].ls[i]=t[nod*2].rs[i]=t[nod*2].ss[i]=t[nod*2].rt-t[nod*2].lt+1;
t[nod*2].sum[i^1]=t[nod*2].ls[i^1]=t[nod*2].rs[i^1]=t[nod*2].ss[i^1]=0;
t[nod*2+1].sum[i]=t[nod*2+1].ls[i]=t[nod*2+1].rs[i]=t[nod*2+1].ss[i]=t[nod*2+1].rt-t[nod*2+1].lt+1;
t[nod*2+1].sum[i^1]=t[nod*2+1].ls[i^1]=t[nod*2+1].rs[i^1]=t[nod*2+1].ss[i^1]=0;
t[nod*2].a[i]=t[nod*2+1].a[i]=1;
t[nod*2].a[i^1]=t[nod*2+1].a[i^1]=t[nod*2].ro=t[nod*2+1].ro=0;
t[nod].a[i]=0;
}
if(t[nod].ro){
t[nod*2].ro^=1;t[nod*2+1].ro^=1;
jh(nod*2);jh(nod*2+1);
if(t[nod*2].a[0]||t[nod*2].a[1])swap(t[nod*2].a[0],t[nod*2].a[1]),t[nod*2].ro=0;
if(t[nod*2+1].a[0]||t[nod*2+1].a[1])swap(t[nod*2+1].a[0],t[nod*2+1].a[1]),t[nod*2+1].ro=0;
t[nod].ro=0;
}
}
inline void build(int l,int r,int nod){
t[nod].pre();
t[nod].lt=l;t[nod].rt=r;
if(l==r){
t[nod].sum[a[l]]=t[nod].ls[a[l]]=t[nod].rs[a[l]]=t[nod].ss[a[l]]=1;
return;
}
int mid=l+r>>1;
build(l,mid,nod*2);build(mid+1,r,nod*2+1);
t[nod]=t[nod*2]+t[nod*2+1];
}
inline void xg(int i,int j,int z,int nod){
pushdown(nod);
if(t[nod].lt>=i&&t[nod].rt<=j){
if(t[nod].a[z])return;
t[nod].sum[z]=t[nod].ls[z]=t[nod].rs[z]=t[nod].ss[z]=t[nod].rt-t[nod].lt+1;
t[nod].sum[z^1]=t[nod].ls[z^1]=t[nod].rs[z^1]=t[nod].ss[z^1]=0;
t[nod].a[z]=1;t[nod].ro=t[nod].a[z^1]=0;
return;
}
int mid=t[nod].lt+t[nod].rt>>1;
if(i<=mid)xg(i,j,z,nod*2);
if(j>mid)xg(i,j,z,nod*2+1);
t[nod]=t[nod*2]+t[nod*2+1];
}
inline void ro(int i,int j,int nod){
pushdown(nod);
if(t[nod].lt>=i&&t[nod].rt<=j){
t[nod].ro^=1;jh(nod);
if(t[nod].a[0]||t[nod].a[1])swap(t[nod].a[0],t[nod].a[1]),t[nod].ro=0;
return;
}
int mid=t[nod].lt+t[nod].rt>>1;
if(i<=mid)ro(i,j,nod*2);
if(j>mid)ro(i,j,nod*2+1);
t[nod]=t[nod*2]+t[nod*2+1];
}
inline int ssum(int i,int j,int nod){
pushdown(nod);
if(t[nod].lt>=i&&t[nod].rt<=j)return t[nod].sum[1];
int mid=t[nod].lt+t[nod].rt>>1,ans=0;
if(i<=mid)ans+=ssum(i,j,nod*2);
if(j>mid)ans+=ssum(i,j,nod*2+1);
return ans;
}
inline tree slong(int i,int j,int nod){
pushdown(nod);
if(t[nod].lt>=i&&t[nod].rt<=j)return t[nod];
int mid=t[nod].lt+t[nod].rt>>1;
if(j<=mid)return slong(i,j,nod*2);
else if(i>mid)return slong(i,j,nod*2+1);
else{
tree X=slong(i,mid,nod*2),Y=slong(mid+1,j,nod*2+1);
return X+Y;
}
}
int main()
{
ios::sync_with_stdio(0);
cin>>n>>m;
for(int i=1;i<=n;i++)cin>>a[i];
build(1,n,1);
for(int i=1;i<=m;i++){
int l,r,z;cin>>z>>l>>r;l++;r++;
if(z<2)xg(l,r,z,1);
if(z==2)ro(l,r,1);
if(z==3)cout<<ssum(l,r,1)<<endl;
if(z==4){
tree p=slong(l,r,1);cout<<p.ss[1]<<endl;
}
}
return 0;
}