Problem Description
lxhgww got a sequence contains n characters which are all '0's or '1's.
We have five operations here:
Change operations:
0 a b change all characters into '0's in [a , b]
1 a b change all characters into '1's in [a , b]
2 a b change all '0's into '1's and change all '1's into '0's in [a, b]
Output operations:
3 a b output the number of '1's in [a, b]
4 a b output the length of the longest continuous '1' string in [a , b]
We have five operations here:
Change operations:
0 a b change all characters into '0's in [a , b]
1 a b change all characters into '1's in [a , b]
2 a b change all '0's into '1's and change all '1's into '0's in [a, b]
Output operations:
3 a b output the number of '1's in [a, b]
4 a b output the length of the longest continuous '1' string in [a , b]
Input
T(T<=10) in the first line is the case number.
Each case has two integers in the first line: n and m (1 <= n , m <= 100000).
The next line contains n characters, '0' or '1' separated by spaces.
Then m lines are the operations:
op a b: 0 <= op <= 4 , 0 <= a <= b < n.
Each case has two integers in the first line: n and m (1 <= n , m <= 100000).
The next line contains n characters, '0' or '1' separated by spaces.
Then m lines are the operations:
op a b: 0 <= op <= 4 , 0 <= a <= b < n.
Output
For each output operation , output the result.
Sample Input
1 10 10 0 0 0 1 1 0 1 0 1 1 1 0 2 3 0 5 2 2 2 4 0 4 0 3 6 2 3 7 4 2 8 1 0 5 0 5 6 3 3 9
Sample Output
5 2 6 5
/*
GANK,直接一个标记.如果是异或则更新到全是0或全是1的地方
*/
#include <iostream>
#include <cstring>
#include <cstdio>
#include <string>
using namespace std;
#define maxn 100008
#define lson 2*id,l,mid
#define rson 2*id+1,mid+1,r
int A[maxn];
inline int max(int a,int b,int c)
{
if(a<b)a=b;
if(a<c)a=c;
return a;
}
struct ST
{
int l,r,len,llen,rlen,set,maxlen;
}st[4*maxn];
void PushUp(int id)
{
st[id].len=st[2*id].len+st[2*id+1].len;
st[id].llen=(st[2*id].llen==st[2*id].r-st[2*id].l+1?st[2*id].len+st[2*id+1].llen:st[2*id].llen);
st[id].rlen=(st[2*id+1].rlen==st[2*id+1].r-st[2*id+1].l+1?st[2*id+1].len+st[2*id].rlen:st[2*id+1].rlen);
st[id].maxlen=max(st[2*id].maxlen,st[2*id+1].maxlen,st[2*id].rlen+st[2*id+1].llen);
}
void PushDown(int id)
{
if(st[id].set!=-1)
{
st[2*id].set=st[2*id+1].set=st[id].set;
if(st[id].set)
{
st[2*id].len=st[2*id].llen=st[2*id].rlen=st[2*id].maxlen=st[2*id].r-st[2*id].l+1;
st[2*id+1].len=st[2*id+1].llen=st[2*id+1].rlen=st[2*id+1].maxlen=st[2*id+1].r-st[2*id+1].l+1;
}
else
{
st[2*id].len=st[2*id].llen=st[2*id].rlen=st[2*id].maxlen=0;
st[2*id+1].len=st[2*id+1].llen=st[2*id+1].rlen=st[2*id+1].maxlen=0;
}
st[id].set=-1;
}
}
void buildtree(int id,int l,int r)
{
st[id].l=l;
st[id].r=r;
if(l==r)
{
st[id].len=st[id].rlen=st[id].llen=st[id].maxlen=A[l];
st[id].set=A[l];
return;
}
int mid=(l+r)>>1;
buildtree(lson);
buildtree(rson);
PushUp(id);
st[id].set=-1;
}
void update(int id,int l,int r,int ope)
{
if(st[id].l==l && st[id].r==r)
{
if(ope==0)
{
st[id].set=0;
st[id].len=st[id].rlen=st[id].llen=st[id].maxlen=0;
return;
}
if(ope==1)
{
st[id].set=1;
st[id].len=st[id].rlen=st[id].llen=st[id].maxlen=st[id].r-st[id].l+1;
return;
}
if(ope==2)
{
if(st[id].set!=-1)
{
st[id].set^=1;
st[id].len=st[id].rlen=st[id].llen=st[id].maxlen=st[id].set?st[id].r-st[id].l+1:0;
return;
}
}
}
PushDown(id);
if(st[2*id].r >= r)
{
update(2*id,l,r,ope);
PushUp(id);
return;
}
if(st[2*id+1].l <= l)
{
update(2*id+1,l,r,ope);
PushUp(id);
return;
}
update(2*id,l,st[2*id].r,ope);
update(2*id+1,st[2*id+1].l,r,ope);
PushUp(id);
}
int query(int id,int l,int r,int ope)
{
if(st[id].l==l && st[id].r==r)
{
if(ope==3)
{
return st[id].len;
}
if(ope==4)
{
return st[id].maxlen;
}
}
PushDown(id);
if(st[2*id].r >= r)
{
return query(2*id,l,r,ope);
}
if(st[2*id+1].l <= l)
{
return query(2*id+1,l,r,ope);
}
if(ope==3)
{
return query(2*id,l,st[2*id].r,ope)+query(2*id+1,st[2*id+1].l,r,ope);
}
else
{
int lllen=min(st[2*id].rlen,st[2*id].r-l+1);
int rrlen=min(st[2*id+1].llen,r-st[2*id+1].l+1);
return max(lllen+rrlen,query(2*id,l,st[2*id].r,ope),query(2*id+1,st[2*id+1].l,r,ope));
}
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%d",&A[i]);
}
int ope,u,v;
buildtree(1,1,n);
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&ope,&u,&v);
if(ope!=3 && ope!=4)
{
update(1,u+1,v+1,ope);
}
else printf("%d\n",query(1,u+1,v+1,ope));
}
}
return 0;
}