HDU 3397 Sequence operation(线段树·成段更新·区间合并·混合操作)
题意 给你一个只有0, 1的数组 有这些操作
将[a, b]区间的所有数都改为0
将[a, b]区间的所有数都改为1
将[a, b]区间的所有数都取反 即与1异或
输出区间[a, b]中1的个数 即所有数的和
输出区间[a, b]中最大连续1的长度
对于所有的3, 4操作输出对应的答案
单个的操作都很简单 但搞在一起就有点恶心了 还好数组里的数只有0和1
线段树维护9个值 对应区间0, 1的最大长度len[i] 对应区间左端点为起点的最大0, 1长度lle[i] 对应区间右端点为终点的最大0, 1长度 对应区间的1的个数sum 对应区间的置值标记setv 对应区间的取反标记opp
成段更新时有两种操作 取反 (opp) 和置值 (setv) 取反操作时因为是0, 1互换 将维护的对应的信息也交换就行了 sum就变成长度减去sum了 置值操作比较简单 但是要注意置值操作前的所有取反操作都是没有意义的 所以置值的时候要将对应区间的取反标记去掉
1 | #include <cstdio> |
Sequence operation
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]
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.
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