hdu3397区间覆盖,区间翻转,区间合并,区间求和

调了很久的代码。。注意区间翻转和覆盖的操作互相的影响

/*
区间替换操作怎么搞?
应该是加个tag标记
如果整个区间都是0|1,那么把若有tag的话直接set1|0即可,也不用设置tag标记
反之要设置tag标记,设置了tag标记的区间mx0和mx1要对换
lazy标记可以覆盖tag
mx0,mx1表示区间0,1最大连续,lmx0,lmx1表示区间左连续,rmx0,rmx1表示区间右连续
*/
#include<bits/stdc++.h>
using namespace std;
#define maxn 200005
int t,n,m,a[maxn]; #define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
int mx0[maxn<<],mx1[maxn<<],lmx0[maxn<<],rmx0[maxn<<],lmx1[maxn<<],rmx1[maxn<<];
int sum[maxn<<],lazy[maxn<<],tag[maxn<<];
void set0(int l,int r,int rt){tag[rt]=;lazy[rt]=;mx0[rt]=lmx0[rt]=rmx0[rt]=r-l+;sum[rt]=mx1[rt]=lmx1[rt]=rmx1[rt]=;}
void set1(int l,int r,int rt){tag[rt]=;lazy[rt]=;mx0[rt]=lmx0[rt]=rmx0[rt]=;sum[rt]=mx1[rt]=lmx1[rt]=rmx1[rt]=r-l+;}
void rev(int l,int r,int rt){
if(lazy[rt]==)set1(l,r,rt);
else if(lazy[rt]==)set0(l,r,rt);
else {
tag[rt]^=;
sum[rt]=r-l+-sum[rt];
swap(mx0[rt],mx1[rt]);
swap(lmx0[rt],lmx1[rt]);
swap(rmx0[rt],rmx1[rt]);
}
}
void pushup(int l,int r,int rt){
int m=l+r>>;
lmx0[rt]=lmx0[rt<<],rmx0[rt]=rmx0[rt<<|];
mx0[rt]=max(mx0[rt<<],mx0[rt<<|]);
if(rmx0[rt<<]==m-l+)lmx0[rt]=lmx0[rt<<|]+m-l+;
if(lmx0[rt<<|]==r-m)rmx0[rt]=rmx0[rt<<]+r-m;
mx0[rt]=max(mx0[rt],max(lmx0[rt],rmx0[rt]));
mx0[rt]=max(mx0[rt],rmx0[rt<<]+lmx0[rt<<|]); lmx1[rt]=lmx1[rt<<],rmx1[rt]=rmx1[rt<<|];
mx1[rt]=max(mx1[rt<<],mx1[rt<<|]);
if(rmx1[rt<<]==m-l+)lmx1[rt]=lmx1[rt<<|]+m-l+;
if(lmx1[rt<<|]==r-m)rmx1[rt]=rmx1[rt<<]+r-m;
mx1[rt]=max(mx1[rt],max(lmx1[rt],rmx1[rt]));
mx1[rt]=max(mx1[rt],rmx1[rt<<]+lmx1[rt<<|]); sum[rt]=sum[rt<<]+sum[rt<<|];
}
void pushdown(int l,int r,int rt){
int m=l+r>>;
if(lazy[rt]==){set0(lson);set0(rson);lazy[rt]=-;return;}
else if(lazy[rt]==){set1(lson),set1(rson);lazy[rt]=-;return;}
else if(tag[rt]){rev(lson);rev(rson);tag[rt]=;return;}
}
void build(int l,int r,int rt){
lazy[rt]=-;
tag[rt]=sum[rt]=;
if(l==r){
if(a[l]==){mx0[rt]=lmx0[rt]=rmx0[rt]=;mx1[rt]=lmx1[rt]=rmx1[rt]=;}
else{mx0[rt]=lmx0[rt]=rmx0[rt]=;mx1[rt]=lmx1[rt]=rmx1[rt]=sum[rt]=;}
return;
}
int m=l+r>>;
build(lson);build(rson);
pushup(l,r,rt);
}
void update0(int L,int R,int l,int r,int rt){
if(L<=l && R>=r){set0(l,r,rt);return;}
int m=l+r>>;
pushdown(l,r,rt);
if(L<=m)update0(L,R,lson);
if(R>m)update0(L,R,rson);
pushup(l,r,rt);
}
void update1(int L,int R,int l,int r,int rt){
if(L<=l && R>=r){set1(l,r,rt);return;}
int m=l+r>>;
pushdown(l,r,rt);
if(L<=m)update1(L,R,lson);
if(R>m)update1(L,R,rson);
pushup(l,r,rt);
}
void update2(int L,int R,int l,int r,int rt){
if(L<=l && R>=r){rev(l,r,rt);return;}
int m=l+r>>;
pushdown(l,r,rt);
if(L<=m)update2(L,R,lson);
if(R>m)update2(L,R,rson);
pushup(l,r,rt);
}
int query1(int L,int R,int l,int r,int rt){
if(L<=l &&R>=r){return sum[rt];}
int m=l+r>>,res=;
pushdown(l,r,rt);
if(L<=m)res+=query1(L,R,lson);
if(R>m)res+=query1(L,R,rson);
pushup(l,r,rt);
return res;
}
int query2(int L,int R,int l,int r,int rt){
if(L<=l && R>=r){return mx1[rt];}
int m=l+r>>;
pushdown(l,r,rt);
if(R<=m)return query2(L,R,lson);
else if(L>m)return query2(L,R,rson);
else {
int t1=query2(L,R,lson),t2=query2(L,R,rson);
int t3=max(t1,t2);
return max(t3,min(rmx1[rt<<],m-L+)+min(lmx1[rt<<|],R-m));
}
pushup(l,r,rt);
} int main(){
cin>>t;
while(t--){
cin>>n>>m;
for(int i=;i<n;i++)cin>>a[i];
build(,n-,);
while(m--){
int opt,l,r;
cin>>opt>>l>>r;
//l++,r++;
if(opt==)update0(l,r,,n-,);
if(opt==)update1(l,r,,n-,);
if(opt==)update2(l,r,,n-,);
if(opt==)cout<<query1(l,r,,n-,)<<'\n';
if(opt==)cout<<query2(l,r,,n-,)<<'\n';
}
}
}
上一篇:java中Collection类及其子类


下一篇:Dos命令讲解