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,2,代表操作,0代表将区间内全部变为0,1代表区间内全部变为1,2代表区间内0,1取反
3,4代表查询,3代表查询区间内1的总数,4代表查询区间内最长连续1的个数
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define lc l,mid,2*i
#define rc mid+1,r,2*i+1
#define lson 2*i
#define rson 2*i+1
const int L = 100000+10;
int n,m;
int s[L];
struct node
{
int l,r;
int ls0,rs0,ms0;//左,右,最大连续0的个数
int ls1,rs1,ms1;//左,右,最大连续1的个数
int sum;//区间内1的总数
int cover,x_or;//覆盖标记与异或标记
} a[L<<2];
void XOR(int i)//区间内0,1,变化就是将0,1有关的数据交换即可
{
swap(a[i].ls0,a[i].ls1);
swap(a[i].rs0,a[i].rs1);
swap(a[i].ms0,a[i].ms1);
a[i].sum = a[i].r-a[i].l+1-a[i].sum;//区间内的总数减去以前1的总数为变换后1的总数
}
void pushup(int i)//1,0都要更新
{
if(a[i].l == a[i].r)
return ;
int len = a[i].r-a[i].l+1;
a[i].ls0 = a[lson].ls0;
a[i].rs0 = a[rson].rs0;
if(a[lson].ls0 == a[lson].r-a[lson].l+1)
a[i].ls0+=a[rson].ls0;
if(a[rson].rs0 == a[rson].r-a[rson].l+1)
a[i].rs0+=a[lson].rs0;
a[i].ms0 = max(max(a[lson].ms0,a[rson].ms0),a[lson].rs0+a[rson].ls0);
a[i].ls1 = a[lson].ls1;
a[i].rs1 = a[rson].rs1;
if(a[lson].ls1 == a[lson].r-a[lson].l+1)
a[i].ls1+=a[rson].ls1;
if(a[rson].rs1 == a[rson].r-a[rson].l+1)
a[i].rs1+=a[lson].rs1;
a[i].ms1 = max(max(a[lson].ms1,a[rson].ms1),a[lson].rs1+a[rson].ls1);
a[i].sum = a[lson].sum+a[rson].sum;
}
void pushdown(int i)
{
if(a[i].l == a[i].r)
return;
if(a[i].cover!=-1)//看区间是被0还是1覆盖了
{
int len = a[i].r-a[i].l+1;
a[lson].cover = a[rson].cover = a[i].cover;
a[lson].x_or = a[rson].x_or = 0;
a[lson].ls0 = a[lson].rs0 = a[lson].ms0 = a[i].cover?0:(len+1)/2;
a[lson].ls1 = a[lson].rs1 = a[lson].ms1 = a[i].cover?(len+1)/2:0;
a[lson].sum = a[i].cover?(len+1)/2:0;
a[rson].ls0 = a[rson].rs0 = a[rson].ms0 = a[i].cover?0:len/2;
a[rson].ls1 = a[rson].rs1 = a[rson].ms1 = a[i].cover?len/2:0;
a[rson].sum = a[i].cover?len/2:0;
a[i].cover = -1;
}
if(a[i].x_or)
{
a[i].x_or = 0;
a[lson].x_or^=1;
a[rson].x_or^=1;
XOR(lson);
XOR(rson);
}
}
void init(int l,int r,int i)
{
a[i].l = l;
a[i].r = r;
a[i].cover = -1;
a[i].x_or = 0;
if(l==r)
{
a[i].ls0 = a[i].rs0 = a[i].ms0 = (s[l]==0);
a[i].ls1 = a[i].rs1 = a[i].ms1 = (s[l]==1);
a[i].cover = s[l];
a[i].sum = s[l];
return;
}
int mid = (l+r)>>1;
init(lc);
init(rc);
pushup(i);
}
void insert(int l,int r,int i,int flag)
{
pushdown(i);//让子树继承父亲的特性,因为要往下更新
if(l<=a[i].l && a[i].r<=r)
{
if(flag<2)
{
int len = a[i].r-a[i].l+1;
a[i].cover = flag;
a[i].ls0 = a[i].rs0 = a[i].ms0 = flag?0:len;
a[i].ls1 = a[i].rs1 = a[i].ms1 = flag?len:0;
a[i].sum = flag?len:0;
}
else
{
a[i].x_or = 1;
XOR(i);
}
}
else
{
if(l<=a[lson].r)
insert(l,r,lson,flag);
if(r>=a[rson].l)
insert(l,r,rson,flag);
pushup(i);
}
}
int query(int l,int r,int i,int flag)
{
pushdown(i);
if(l<=a[i].l && a[i].r<=r)
{
if(flag == 3) return a[i].sum;
else return a[i].ms1;
}
else
{
if(r<=a[lson].r) return query(l,r,lson,flag);
if(l>=a[rson].l) return query(l,r,rson,flag);
if(flag == 3)
return query(l,a[lson].r,lson,flag)+query(a[rson].l,r,rson,flag);
int ans1 = min(a[lson].rs1,a[lson].r-l+1)+min(a[rson].ls1,r-a[rson].l+1);
int ans2 = max(query(l,a[lson].r,lson,flag),query(a[rson].l,r,rson,flag));
return max(ans1,ans2);
}
}
int main()
{
int t,l,r,flag;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
for(int i = 1;i<=n;i++)
scanf("%d",&s[i]);
init(1,n,1);
while(m--)
{
scanf("%d%d%d",&flag,&l,&r);
l++;
r++;
if(flag<3)
insert(l,r,1,flag);
else
printf("%d\n",query(l,r,1,flag));
}
}
return 0;
}