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 a b将区间[a,b]所有数全部变成0
1 a b将区间[a,b]所有数全部变成1
2 a b将区间[a,b]中所有数0 1互换,0变1,1变0
3 a b输出区间[a,b]中1的个数
4 a b输出区间[a,b]中最长连续1的个数
1 a b将区间[a,b]所有数全部变成1
2 a b将区间[a,b]中所有数0 1互换,0变1,1变0
3 a b输出区间[a,b]中1的个数
4 a b输出区间[a,b]中最长连续1的个数
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
struct node
{
int l, r, sum;
int ls1, rs1, ms1;
int ls0, rs0, ms0;
int flag1, flag2;
}tree[1000000];
int a[1000000];
void function(int id)
{
swap(tree[id].ls0, tree[id].ls1);
swap(tree[id].rs0, tree[id].rs1);
swap(tree[id].ms0, tree[id].ms1);
tree[id].sum = tree[id].r - tree[id].l + 1 - tree[id].sum;
}
void pushup(int id)
{
if (tree[id].l == tree[id].r)
return;
tree[id].sum = tree[2 * id].sum + tree[2 * id + 1].sum;
tree[id].ls0 = tree[2 * id].ls0, tree[id].rs0 = tree[2 * id + 1].rs0;
tree[id].ls1 = tree[2 * id].ls1, tree[id].rs1 = tree[2 * id + 1].rs1;
if (tree[id * 2].r - tree[2 * id].l + 1 == tree[2 * id].ls1)
tree[id].ls1 += tree[2 * id + 1].ls1;
if (tree[id * 2].r - tree[2 * id].l + 1 == tree[2 * id].ls0)
tree[id].ls0 += tree[2 * id + 1].ls0;
if (tree[2 * id + 1].r - tree[2 * id + 1].l + 1 == tree[id * 2 + 1].rs1)
tree[id].rs1 += tree[2 * id].rs1;
if (tree[2 * id + 1].r - tree[2 * id + 1].l + 1 == tree[id * 2 + 1].rs0)
tree[id].rs0 += tree[2 * id].rs0;
tree[id].ms1 = max(max(tree[2 * id].ms1, tree[2 * id + 1].ms1), tree[2 * id].rs1 + tree[2 * id + 1].ls1);
tree[id].ms0 = max(max(tree[2 * id].ms0, tree[2 * id + 1].ms0), tree[2 * id].rs0 + tree[2 * id + 1].ls0);
}
void pushdown(int id)
{
if (tree[id].l == tree[id].r)
return;
if (tree[id].flag1 != -1)
{
int len = tree[id].r - tree[id].l + 1;
tree[2*id].flag1 = tree[2*id+1].flag1 = tree[id].flag1;
tree[2*id].flag2 = tree[2*id+1].flag2 = 0;
tree[2*id].ls0 = tree[2*id].rs0 = tree[2*id].ms0 = tree[id].flag1 ? 0 : (len + 1) / 2;
tree[2*id].ls1 = tree[2*id].rs1 = tree[2*id].ms1 = tree[id].flag1 ? (len + 1) / 2 : 0;
tree[2*id].sum = tree[id].flag1 ? (len + 1) / 2 : 0;
tree[2*id+1].ls0 = tree[2*id+1].rs0 = tree[2*id+1].ms0 = tree[id].flag1 ? 0 : len / 2;
tree[2*id+1].ls1 = tree[2*id+1].rs1 = tree[2*id+1].ms1 = tree[id].flag1 ? len / 2 : 0;
tree[2*id+1].sum = tree[id].flag1 ? len / 2 : 0;
tree[id].flag1 = -1;
}
if (tree[id].flag2 != 0)
{
tree[id].flag2 = 0;
tree[2 * id].flag2 ^= 1, tree[2 * id + 1].flag2 ^= 1;
function(2 * id), function(2 * id + 1);
}
}
void build(int id, int l, int r)
{
tree[id].l = l, tree[id].r = r;
tree[id].flag1 = -1, tree[id].flag2 = 0;
if (l == r)
{
tree[id].flag1=tree[id].sum = a[l];
if (a[l] == 0)
{
tree[id].ms0 = tree[id].ls0 = tree[id].rs0 = 1;
tree[id].ms1 = tree[id].ls1 = tree[id].rs1 = 0;
}
if (a[l] == 1)
{
tree[id].ms0 = tree[id].ls0 = tree[id].rs0 = 0;
tree[id].ms1 = tree[id].ls1 = tree[id].rs1 = 1;
}
return;
}
int mid = (l + r) / 2;
build(2 * id, l, mid);
build(2 * id + 1, mid + 1, r);
pushup(id);
}
void update(int id, int l, int r, int t)
{
pushdown(id);
if (l <= tree[id].l&&tree[id].r <= r)
{
int len = tree[id].r - tree[id].l + 1;
if (t == 0)
{
tree[id].ls1 = tree[id].rs1 = tree[id].ms1 = tree[id].flag1 = tree[id].sum = 0;
tree[id].ls0 = tree[id].rs0 = tree[id].ms0 = len;
}
if (t == 1)
{
tree[id].ls0 = tree[id].rs0 = tree[id].ms0 = 0, tree[id].flag1 = 1;
tree[id].sum = tree[id].ls1 = tree[id].rs1 = tree[id].ms1 = len;
}
if (t == 2)
{
tree[id].flag2 = 1;
function(id);
}
return;
}
if (l <= tree[2 * id].r) update(2 * id, l, r, t);
if (r >= tree[2 * id + 1].l) update(2 * id + 1, l, r, t);
pushup(id);
}
int query(int id, int l, int r, int t)
{
pushdown(id);
if (l <= tree[id].l&&tree[id].r <= r)
{
if (t == 3) return tree[id].sum;
else return tree[id].ms1;
}
if (r <= tree[2 * id].r) return query(2 * id, l, r, t);
if (l >= tree[2 * id + 1].l) return query(2 * id + 1, l, r, t);
if (t == 3) return query(2 * id, l, tree[2 * id].r, t) + query(2 * id + 1, tree[2 * id + 1].l, r, t);
int ans1 = min(tree[2 * id].rs1, tree[2 * id].r - l + 1) + min(tree[2 * id + 1].ls1, r - tree[2 * id + 1].l + 1);
int ans2 = max(query(2 * id, l, tree[2 * id].r, t), query(2 * id + 1, tree[2 * id + 1].l, r, t));
return max(ans1, ans2);
}
int main()
{
int t, l, r, t1, n, m;
scanf("%d", &t1);
while (t1--)
{
memset(a, -1, sizeof(a));
scanf("%d%d", &n, &m);
for (int i = 1;i <= n;i++)
scanf("%d", &a[i]);
build(1, 1, n);
while (m--)
{
scanf("%d%d%d", &t, &l, &r); l++, r++;
if (t < 3)
update(1, l, r, t);
else printf("%d\n", query(1, l, r, t));
}
}
system("pause");
return 0;
}