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
这道题是前面线段树知识的综合题,也和之前有些不同,是个很好的训练题,做了很长时间啊,还需努力。这里的难点是异或运算,即把区间中的0变成1,1变成0.这里我维护每个区间的llen0,rlen0,tlen0,llen1,rlen1,tlen1,即区间从左端点起的向右最大连续0(1)区间长度,从右端起的最大向左连续0(1)区间长度,以及区间最大的连续0(1)区间长度,然后异或操作的时候,只要把0,1换一下,然后用pushup操作就可以了,再记录一个异或操作符x_or.
<pre name="code" class="cpp">#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<string>
#include<algorithm>
using namespace std;
typedef long long ll;
#define inf 0x7fffffff
#define maxn 100050
int a[maxn];
struct node{
int l,r,yihuo,cnt;
int llen0,rlen0,tlen0;
int llen1,rlen1,tlen1;
int num0,num1;
}b[4*maxn];
int num1,num2;
void pushdown(int i)
{
if(b[i].l==b[i].r)return;
if(b[i].cnt!=-1){
b[i*2].cnt=b[i*2+1].cnt=b[i].cnt;
b[i*2].yihuo=b[i*2+1].yihuo=0;
if(b[i].cnt==0){
b[i*2].llen0=b[i*2].rlen0=b[i*2].tlen0=b[i*2].r-b[i*2].l+1;
b[i*2].llen1=b[i*2].rlen1=b[i*2].tlen1=0;
b[i*2].num0=b[i*2].r-b[i*2].l+1;
b[i*2].num1=0;
b[i*2+1].llen0=b[i*2+1].rlen0=b[i*2+1].tlen0=b[i*2+1].r-b[i*2+1].l+1;
b[i*2+1].llen1=b[i*2+1].rlen1=b[i*2+1].tlen1=0;
b[i*2+1].num0=b[i*2+1].r-b[i*2+1].l+1;
b[i*2+1].num1=0;
}
else if(b[i].cnt==1){
b[i*2].llen0=b[i*2].rlen0=b[i*2].tlen0=0;
b[i*2].llen1=b[i*2].rlen1=b[i*2].tlen1=b[i*2].r-b[i*2].l+1;
b[i*2].num0=0;
b[i*2].num1=b[i*2].r-b[i*2].l+1;
b[i*2+1].llen0=b[i*2+1].rlen0=b[i*2+1].tlen0=0;
b[i*2+1].llen1=b[i*2+1].rlen1=b[i*2+1].tlen1=b[i*2+1].r-b[i*2+1].l+1;
b[i*2+1].num0=0;
b[i*2+1].num1=b[i*2+1].r-b[i*2+1].l+1;
}
b[i].cnt=-1;
}
if(b[i].yihuo!=0){
b[i*2].yihuo=1^b[i*2].yihuo;
swap(b[i*2].llen0,b[i*2].llen1);
swap(b[i*2].rlen0,b[i*2].rlen1);
swap(b[i*2].tlen0,b[i*2].tlen1);
swap(b[i*2].num0,b[i*2].num1);
/*
if(b[i*2].cnt!=-1){ 这里和下面注释的不能写,因为如果换了的话就和父亲节点的信息不同了
b[i*2].cnt^=1;
}
*/
b[i*2+1].yihuo=1^b[i*2+1].yihuo;
swap(b[i*2+1].llen0,b[i*2+1].llen1);
swap(b[i*2+1].rlen0,b[i*2+1].rlen1);
swap(b[i*2+1].tlen0,b[i*2+1].tlen1);
swap(b[i*2+1].num0,b[i*2+1].num1);
/*
if(b[i*2+1].cnt!=-1){
b[i*2+1].cnt^=1;
}
*/
b[i].yihuo=0;
}
}
void pushup(int i)
{
if(b[i].l==b[i].r)return;
b[i].num0=b[i*2].num0+b[i*2+1].num0;
b[i].num1=b[i*2].num1+b[i*2+1].num1;
b[i].llen0=b[i*2].llen0;
b[i].rlen0=b[i*2+1].rlen0;
if(b[i*2].llen0==b[i*2].r-b[i*2].l+1){
b[i].llen0+=b[i*2+1].llen0;
}
if(b[i*2+1].rlen0==b[i*2+1].r-b[i*2+1].l+1){
b[i].rlen0+=b[i*2].rlen0;
}
b[i].tlen0=max(b[i*2].tlen0,b[i*2+1].tlen0);
b[i].tlen0=max(b[i*2].rlen0+b[i*2+1].llen0,b[i].tlen0);
b[i].llen1=b[i*2].llen1;
b[i].rlen1=b[i*2+1].rlen1;
if(b[i*2].llen1==b[i*2].r-b[i*2].l+1){
b[i].llen1+=b[i*2+1].llen1;
}
if(b[i*2+1].rlen1==b[i*2+1].r-b[i*2+1].l+1){
b[i].rlen1+=b[i*2].rlen1;
}
b[i].tlen1=max(b[i*2].tlen1,b[i*2+1].tlen1);
b[i].tlen1=max(b[i*2].rlen1+b[i*2+1].llen1,b[i].tlen1);
}
void build(int l,int r,int i)
{
int mid;
b[i].l=l;b[i].r=r;b[i].yihuo=0;b[i].cnt=-1;
if(l==r){
if(a[l]==0){
b[i].llen0=b[i].rlen0=b[i].tlen0=1;
b[i].llen1=b[i].rlen1=b[i].tlen1=0;
b[i].num0=1;
b[i].num1=0;
}
else{
b[i].llen0=b[i].rlen0=b[i].tlen0=0;
b[i].llen1=b[i].rlen1=b[i].tlen1=1;
b[i].num0=0;
b[i].num1=1;
}
return;
}
mid=(l+r)/2;
build(l,mid,i*2);
build(mid+1,r,i*2+1);
pushup(i);
}
void update01(int l,int r,int num,int i)
{
int mid;
if(b[i].l==l && b[i].r==r){
b[i].yihuo=0;
b[i].cnt=num;
if(num==0){
b[i].llen0=b[i].rlen0=b[i].tlen0=b[i].r-b[i].l+1;
b[i].llen1=b[i].rlen1=b[i].tlen1=0;
b[i].num0=b[i].r-b[i].l+1;
b[i].num1=0;
}
else{
b[i].llen0=b[i].rlen0=b[i].tlen0=0;
b[i].llen1=b[i].rlen1=b[i].tlen1=b[i].r-b[i].l+1;
b[i].num0=0;
b[i].num1=b[i].r-b[i].l+1;
}
return;
}
pushdown(i);
mid=(b[i].l+b[i].r)/2;
if(r<=mid)update01(l,r,num,i*2);
else if(l>mid)update01(l,r,num,i*2+1);
else{
update01(l,mid,num,i*2);
update01(mid+1,r,num,i*2+1);
}
pushup(i);
}
void update2(int l,int r,int i)
{
int mid;
if(b[i].l==l && b[i].r==r){
b[i].yihuo=1^b[i].yihuo;
swap(b[i].llen0,b[i].llen1);
swap(b[i].rlen0,b[i].rlen1);
swap(b[i].tlen0,b[i].tlen1);
swap(b[i].num0,b[i].num1);
//if(b[i].cnt!=-1)b[i].cnt^=1;这句不用写
return;
}
pushdown(i);//pushdown(i)放上面下面都行的
mid=(b[i].l+b[i].r)/2;
if(r<=mid)update2(l,r,i*2);
else if(l>mid)update2(l,r,i*2+1);
else{
update2(l,mid,i*2);
update2(mid+1,r,i*2+1);
}
pushup(i);
}
void question1(int l,int r,int i)
{
int mid;
if(b[i].l==l && b[i].r==r){
num1+=b[i].num1;
return;
}
pushdown(i);
mid=(b[i].l+b[i].r)/2;
if(r<=mid)question1(l,r,i*2);
else if(l>mid)question1(l,r,i*2+1);
else{
question1(l,mid,i*2);
question1(mid+1,r,i*2+1);
}
}
int question2(int l,int r,int i)
{
int mid;
if(b[i].l==l && b[i].r==r){
return b[i].tlen1;
}
pushdown(i);
mid=(b[i].l+b[i].r)/2;
if(r<=mid){
return question2(l,r,i*2);
}
else if(l>mid){
return question2(l,r,i*2+1);
}
else{
int l1,r1;
l1=max(b[i*2].r-b[i*2].rlen1+1,l);
r1=min(b[i*2+1].l+b[i*2+1].llen1-1,r);
int temp=r1-l1+1;
temp=max(temp,question2(l,mid,i*2) );
temp=max(temp,question2(mid+1,r,i*2+1));
return temp;
}
}
int main()
{
int n,m,i,j,T,f,c,d;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++){
scanf("%d",&a[i]);
}
build(1,n,1);
for(i=1;i<=m;i++){
scanf("%d%d%d",&f,&c,&d);
c++;d++;
if(f==0){
update01(c,d,0,1);
}
if(f==1){
update01(c,d,1,1);
}
else if(f==2){
update2(c,d,1);
}
else if(f==3){
num1=0;
question1(c,d,1);
printf("%d
",num1);
}
else if(f==4){
printf("%d
",question2(c,d,1));
}
}
}
return 0;
}