Sequence operation
更新区间,区间染色,区间合并
Q:
对于一个01序列
区间修改为0/1
区间每个数修改为异或
查询区间最长1序列
查询区间1的个数
易错点_1
标记先后顺序,能否同时存在(此题中我的写法同时存在会有BUG)
如:downFlag, update
void update(int o, int l, int r){
int mid=(l+r)>>1, llen=mid-l+1, rlen=r-(mid+1)+1;
if(l!=r){
For(t,0,1){
T[o].a[t].s=max(T[o<<1].a[t].ssuff+T[o<<1|1].a[t].spre,
max(T[o<<1].a[t].s, T[o<<1|1].a[t].s));
//pre
if(T[o<<1].a[t].s==llen) T[o].a[t].spre=llen+T[o<<1|1].a[t].spre;
else T[o].a[t].spre=T[o<<1].a[t].spre;
//suff
if(T[o<<1|1].a[t].s==rlen) T[o].a[t].ssuff=rlen+T[o<<1].a[t].ssuff;
else T[o].a[t].ssuff=T[o<<1|1].a[t].ssuff;
T[o].s[t]=T[o<<1].s[t]+T[o<<1|1].s[t];
}
}
int c=T[o].c;
if(c>=0) T[o].a[c]=(Data){r-l+1,r-l+1,r-l+1}, T[o].a[c^1]=(Data){0,0,0}, T[o].s[c]=r-l+1, T[o].s[1-c]=0;
if(T[o].xo) swap(T[o].a[0], T[o].a[1]), swap(T[o].s[0], T[o].s[1]);
}
void downFlag(int o, int l, int r){
int mid=(l+r)>>1;
if(T[o].c>=0){ //Attention
addFlag(T[o].c,LSON); addFlag(T[o].c,RSON);
update(LSON); update(RSON);
T[o].c=-1;
}
if(T[o].xo){ //Attention
addFlag(-1,LSON); addFlag(-1,RSON);
update(LSON); update(RSON);
T[o].xo=0;
}
}
易错点_2
叶节点更新时要特别注意
如:update, addFlag
void addFlag(int x, int o, int l, int r){
if(l==r){ //Attention
if(x>=0){
T[o].a[x]=(Data){1,1,1}; T[o].a[x^1]=(Data){0,0,0};
T[o].s[x]=1; T[o].s[1-x]=0;
} else {
swap(T[o].a[0], T[o].a[1]); swap(T[o].s[0], T[o].s[1]);
}
} else {
if(x>=0) T[o].c=x, T[o].xo=0;
else T[o].xo^=1;
}
}
易错点_3
小细节
如:query
int query(int L, int R, int o, int l, int r, int xo){
int sum=0;
if(T[o].c>=0){
if(T[o].c ^ xo ^ T[o].xo) sum=min(r, R)-max(l, L)+1;
//注意区间长度,不要误写成r-l+1
} else if(L<=l && r<=R){
sum=T[o].s[xo^1];
} else {
int mid=(l+r)>>1;
if(L<=mid) sum+=query(L, R, LSON, xo^T[o].xo);//注意算上区间的标记
if(R>mid) sum+=query(L, R, RSON, xo^T[o].xo);
}
return sum;
}
附冗长代码
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
#include <vector>
#define File(x) "test."#x
#define For(i,s,e) for(int i=(s); i<=(e); i++)
#define Rep(i,s,e) for(int i=(s); i>=(e); i--)
#define LSON o<<1, l, mid
#define RSON o<<1|1, mid+1, r
using namespace std;
const int N=1000000+1;
struct Data{
int s,spre,ssuff;
};
struct Node{
Data a[2]; int c,s[2];
bool xo;
}T[N];
int Q,n,m,val[N];
void update(int o, int l, int r){
int mid=(l+r)>>1, llen=mid-l+1, rlen=r-(mid+1)+1;
if(l!=r){ //Attention
For(t,0,1){
T[o].a[t].s=max(T[o<<1].a[t].ssuff+T[o<<1|1].a[t].spre,
max(T[o<<1].a[t].s, T[o<<1|1].a[t].s));
//pre
if(T[o<<1].a[t].s==llen) T[o].a[t].spre=llen+T[o<<1|1].a[t].spre;
else T[o].a[t].spre=T[o<<1].a[t].spre;
//suff
if(T[o<<1|1].a[t].s==rlen) T[o].a[t].ssuff=rlen+T[o<<1].a[t].ssuff;
else T[o].a[t].ssuff=T[o<<1|1].a[t].ssuff;
T[o].s[t]=T[o<<1].s[t]+T[o<<1|1].s[t];
}
}
int c=T[o].c;
if(c>=0) T[o].a[c]=(Data){r-l+1,r-l+1,r-l+1}, T[o].a[c^1]=(Data){0,0,0}, T[o].s[c]=r-l+1, T[o].s[1-c]=0;
if(T[o].xo) swap(T[o].a[0], T[o].a[1]), swap(T[o].s[0], T[o].s[1]);
}
void build(int o, int l, int r){
T[o].xo=0; T[o].c=-1;
if(l==r){
T[o].a[val[l]]=(Data){1,1,1}; T[o].a[val[l]^1]=(Data){0,0,0};
T[o].s[val[l]]=1; T[o].s[1-val[l]]=0;
return;
}
int mid=(l+r)>>1;
build(RSON); build(LSON);
update(o,l,r);
}
void addFlag(int x, int o, int l, int r){
if(l==r){ //Attention
if(x>=0){
T[o].a[x]=(Data){1,1,1}; T[o].a[x^1]=(Data){0,0,0};
T[o].s[x]=1; T[o].s[1-x]=0;
} else {
swap(T[o].a[0], T[o].a[1]); swap(T[o].s[0], T[o].s[1]);
}
} else {
if(x>=0) T[o].c=x, T[o].xo=0;//Attention
else T[o].xo^=1;
}
}
void downFlag(int o, int l, int r){
int mid=(l+r)>>1;
if(T[o].c>=0){//Attention
addFlag(T[o].c,LSON); addFlag(T[o].c,RSON);
update(LSON); update(RSON);
T[o].c=-1;
}
if(T[o].xo){
addFlag(-1,LSON); addFlag(-1,RSON);
update(LSON); update(RSON);
T[o].xo=0;
}
}
void modify(int x, int L, int R, int o, int l, int r){
if(L<=l && r<=R){
addFlag(x,o,l,r);
} else {
downFlag(o,l,r);
int mid=(l+r)>>1;
if(L<=mid) modify(x, L, R, LSON); else update(LSON);
if(R>mid) modify(x, L, R, RSON); else update(RSON);
}
update(o,l,r);
}
void query(int L, int R, int o, int l, int r, int xo, int &sum, int &spre, int &ssuff){
if(T[o].c>=0){
if(T[o].c ^ xo ^ T[o].xo) sum=min(r, R)-max(l, L)+1, spre=sum, ssuff=sum;
//Attention
} else if(L<=l && r<=R){
sum=T[o].a[xo^1].s; spre=T[o].a[xo^1].spre; ssuff=T[o].a[xo^1].ssuff;
} else {
int _suml=0,_prel=0,_suffl=0,mid=(l+r)>>1,llen=mid-max(l, L)+1, rlen=min(R, r)-(mid+1)+1;
int _sumr=0,_prer=0,_suffr=0;
if(L<=mid) query(L,R,LSON,xo^T[o].xo,_suml,_prel,_suffl);
if(R>mid) query(L,R,RSON,xo^T[o].xo,_sumr,_prer,_suffr);
sum=max(_suffl+_prer, max(_suml, _sumr));
//pre
if(_suml==llen) spre=_suml+_prer;
else spre=_prel;
//suff
if(_sumr==rlen) ssuff=_sumr+_suffl;
else ssuff=_suffr;
}
}
int query(int L, int R, int o, int l, int r, int xo){
int sum=0;
if(T[o].c>=0){
if(T[o].c ^ xo ^ T[o].xo) sum=min(r, R)-max(l, L)+1;
} else if(L<=l && r<=R){
sum=T[o].s[xo^1];
} else {
int mid=(l+r)>>1;
if(L<=mid) sum+=query(L, R, LSON, xo^T[o].xo);
if(R>mid) sum+=query(L, R, RSON, xo^T[o].xo);
}
return sum;
}
int main()
{
freopen(File(in),"r",stdin);
freopen(File(out),"w",stdout);
// ios::sync_with_stdio(false);
scanf("%d",&Q);
while(Q--){
scanf("%d%d",&n,&m);
For(i,1,n) scanf("%d",&val[i]);
build(1,1,n);
while(m--){
int opt,a,b; scanf("%d%d%d",&opt,&a,&b);
a++, b++;
if(opt==0) modify(opt,a,b,1,1,n);
if(opt==1) modify(opt,a,b,1,1,n);
if(opt==2) modify(-1,a,b,1,1,n);
if(opt==3) printf("%d\n",query(a,b,1,1,n,0));
if(opt==4){
int sum,pre,suff;
query(a,b,1,1,n,0,sum,pre,suff);
printf("%d\n",sum);
}
}
}
return 0;
}