给出一个长度为N(N <= 100000)的数列,然后是五种操作:
插入操作:
0 a b 将所有[a, b]区间内的数改成0
1 a b 将所有[a, b]区间内的数改成1
2 a b 将所有[a, b]区间内的数异或一下(0边1,1变0)
输出操作:
3 a b 输出[a, b]区间内1的数量
4 a b 输出[a, b]区间内最长的连续1串
插入操作:
0 a b 将所有[a, b]区间内的数改成0
1 a b 将所有[a, b]区间内的数改成1
2 a b 将所有[a, b]区间内的数异或一下(0边1,1变0)
输出操作:
3 a b 输出[a, b]区间内1的数量
4 a b 输出[a, b]区间内最长的连续1串
setbuf太坑了 一直TLE T_T 去掉就过了
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define for if(0); else for
struct SegNode{
int lc[2],rc[2],cc[2];
int sum[2];
char color,xorflag,emptyflag;
};
const int N=65536*2+10;
struct SegTree{
SegNode a[N<<2];
int n,Q;
void Init(int n){
for(Q=1;Q<=n+2;Q<<=1);
this->n=n;
}
void cover(int rt,int c,int L){
SegNode &x=a[rt];
x.lc[c]=x.rc[c]=x.cc[c]=x.sum[c]=L;
x.lc[c^1]=x.rc[c^1]=x.cc[c^1]=x.sum[c^1]=0;
x.color=c;
x.xorflag=0;
x.emptyflag=0;
}
void XOR(int rt,int L){
SegNode &x=a[rt];
if(x.color!=-1){
x.color^=1;
cover(rt,x.color,L);
}else {
swap(x.lc[0],x.lc[1]);
swap(x.rc[0],x.rc[1]);
swap(x.cc[0],x.cc[1]);
swap(x.sum[0],x.sum[1]);
x.xorflag^=1;
}
}
SegNode merge(const SegNode &l,const SegNode &r,int L,int mode=0)const {
if(l.emptyflag) return r;
SegNode ret;
for(int i=0;i<2;i++){
if(i==0 &&mode )continue;
ret.lc[i]=l.lc[i];
ret.rc[i]=r.rc[i];
ret.cc[i]=max(max(l.cc[i],r.cc[i]),l.rc[i]+r.lc[i]);
if(l.lc[i]==L>>1) ret.lc[i]+=r.lc[i];
if(r.rc[i]==L>>1) ret.rc[i]+=l.rc[i];
ret.sum[i]=l.sum[i]+r.sum[i];
}
ret.color=(l.color==r.color)?l.color:-1;
ret.xorflag=ret.emptyflag=0;
return ret;
}
void pushdown(int rt,int L){
if(a[rt].color!=-1){
cover(rt<<1,a[rt].color,L>>1);
cover(rt<<1|1,a[rt].color,L>>1);}
if(a[rt].xorflag){
XOR(rt<<1,L>>1);
XOR(rt<<1|1,L>>1);
a[rt].xorflag=0;}
}
void pushup(int rt,int L){
if(rt>=Q) return;
a[rt]=merge(a[rt<<1],a[rt<<1|1],L);
}
void update(int L,int R,int l,int r,int rt,int op){
if(op<2 &&a[rt].color==op) return;
if(L<=l && r<=R){
if(op<2) cover(rt,op,r-l+1);
else XOR(rt,r-l+1);
return;
}
int m=(l+r)>>1;
if(rt>=Q) return;
pushdown(rt,r-l+1);
if(L<=m) update(L,R,l,m,rt<<1,op);
if(m<R) update(L,R,m+1,r,rt<<1|1,op);
pushup(rt,r-l+1);
}
SegNode query(int L,int R,int l,int r,int rt){
SegNode ret;
ret.emptyflag=1;
if(L<=l && r<=R){
return a[rt];
}
if(rt>=Q) return ret;
int m=(l+r)>>1;
pushdown(rt,r-l+1);
if(L<=m) ret=merge(ret,query(L,R,l,m,rt<<1),r-l+1);
if(m<R) ret=merge(ret,query(L,R,m+1,r,rt<<1|1),r-l+1);
return ret;
}
void update(int L,int R,int op){
update(L,R,0,Q-1,1,op);
}
SegNode query(int L,int R){
return query(L,R,0,Q-1,1);
}
}st;
int T,n,m;
int main() {
scanf("%d",&T);
while(T--){
scanf("%d %d",&n,&m);
st.Init(n+10);
for(int i=1;i<=n;i++){
int x;
scanf("%d",&x);
st.update(i,i,x);
}
for(int i=0;i<m;i++){
int op,l,r;
scanf("%d %d %d",&op,&l,&r);
l++,r++;
if(op<=2){
st.update(l,r,op);
}else{
SegNode ans=st.query(l,r);
if(op==3){
printf("%d\n",ans.sum[1]);
}else if(op==4){
printf("%d\n",ans.cc[1]);
}
}
}
}
return 0;
}
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define for if(0); else for
struct SegNode{
int lc[2],rc[2],cc[2];
int sum[2];
char color,xorflag,emptyflag;
};
const int N=65536*2+10;
struct SegTree{
SegNode a[N<<2];
int n,Q;
void Init(int n){
for(Q=1;Q<=n+2;Q<<=1);
this->n=n;
}
void cover(int rt,int c,int L){
SegNode &x=a[rt];
x.lc[c]=x.rc[c]=x.cc[c]=x.sum[c]=L;
x.lc[c^1]=x.rc[c^1]=x.cc[c^1]=x.sum[c^1]=0;
x.color=c;
x.xorflag=0;
x.emptyflag=0;
}
void XOR(int rt,int L){
SegNode &x=a[rt];
if(x.color!=-1){
x.color^=1;
cover(rt,x.color,L);
}else {
swap(x.lc[0],x.lc[1]);
swap(x.rc[0],x.rc[1]);
swap(x.cc[0],x.cc[1]);
swap(x.sum[0],x.sum[1]);
x.xorflag^=1;
}
}
SegNode merge(const SegNode &l,const SegNode &r,int L,int mode=0)const {
if(l.emptyflag) return r;
SegNode ret;
for(int i=0;i<2;i++){
if(i==0 &&mode )continue;
ret.lc[i]=l.lc[i];
ret.rc[i]=r.rc[i];
ret.cc[i]=max(max(l.cc[i],r.cc[i]),l.rc[i]+r.lc[i]);
if(l.lc[i]==L>>1) ret.lc[i]+=r.lc[i];
if(r.rc[i]==L>>1) ret.rc[i]+=l.rc[i];
ret.sum[i]=l.sum[i]+r.sum[i];
}
ret.color=(l.color==r.color)?l.color:-1;
ret.xorflag=ret.emptyflag=0;
return ret;
}
void pushdown(int rt,int L){
if(a[rt].color!=-1){
cover(rt<<1,a[rt].color,L>>1);
cover(rt<<1|1,a[rt].color,L>>1);}
if(a[rt].xorflag){
XOR(rt<<1,L>>1);
XOR(rt<<1|1,L>>1);
a[rt].xorflag=0;}
}
void pushup(int rt,int L){
if(rt>=Q) return;
a[rt]=merge(a[rt<<1],a[rt<<1|1],L);
}
void update(int L,int R,int l,int r,int rt,int op){
if(op<2 &&a[rt].color==op) return;
if(L<=l && r<=R){
if(op<2) cover(rt,op,r-l+1);
else XOR(rt,r-l+1);
return;
}
int m=(l+r)>>1;
if(rt>=Q) return;
pushdown(rt,r-l+1);
if(L<=m) update(L,R,l,m,rt<<1,op);
if(m<R) update(L,R,m+1,r,rt<<1|1,op);
pushup(rt,r-l+1);
}
SegNode query(int L,int R,int l,int r,int rt){
SegNode ret;
ret.emptyflag=1;
if(L<=l && r<=R){
return a[rt];
}
if(rt>=Q) return ret;
int m=(l+r)>>1;
pushdown(rt,r-l+1);
if(L<=m) ret=merge(ret,query(L,R,l,m,rt<<1),r-l+1);
if(m<R) ret=merge(ret,query(L,R,m+1,r,rt<<1|1),r-l+1);
return ret;
}
void update(int L,int R,int op){
update(L,R,0,Q-1,1,op);
}
SegNode query(int L,int R){
return query(L,R,0,Q-1,1);
}
}st;
int T,n,m;
int main() {
scanf("%d",&T);
while(T--){
scanf("%d %d",&n,&m);
st.Init(n+10);
for(int i=1;i<=n;i++){
int x;
scanf("%d",&x);
st.update(i,i,x);
}
for(int i=0;i<m;i++){
int op,l,r;
scanf("%d %d %d",&op,&l,&r);
l++,r++;
if(op<=2){
st.update(l,r,op);
}else{
SegNode ans=st.query(l,r);
if(op==3){
printf("%d\n",ans.sum[1]);
}else if(op==4){
printf("%d\n",ans.cc[1]);
}
}
}
}
return 0;
}