OI技术宅

Tech Otakus save the world!
Welcome,my dear friends!
【I'm kiana/kiana810@126.com】

【SCOI2010】序列操作

【题目描述】

lxhgww最近收到了一个01序列,序列里面包含了n个数,这些数要么是0,要么是1,现在对于这个序列有五种变换操作和询问操作:
0 a b 把[a, b]区间内的所有数全变成0
1 a b 把[a, b]区间内的所有数全变成1
2 a b 把[a,b]区间内的所有数全部取反,也就是说把所有的0变成1,把所有的1变成0
3 a b 询问[a, b]区间内总共有多少个1
4 a b 询问[a, b]区间内最多有多少个连续的1
对于每一种询问操作,lxhgww都需要给出回答,聪明的程序员们,你们能帮助他吗?

【输入】

输入数据第一行包括2个数,n和m,分别表示序列的长度和操作数目
第二行包括n个数,表示序列的初始状态
接下来m行,每行3个数,op, a, b,(0<=op<=4,0<=a<=b<n)表示对于区间[a, b]执行标号为op的操作

【输出】

对于每一个询问操作,输出一行,包括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

【输出样例】

5
2
6
5

【数据范围】

对于30%的数据,1<=n, m<=1000
对于100%的数据,1<=n, m<=100000

【题解】

多标记的线段树题,每个区间维护这些值:0和1的个数,最多的连续的0和1的个数,区间最左边和最右边连续的0和1的个数。合并信息时要处理某个区间全为0或全为1的特殊情况,其余的还是很好处理的。

然后是标记,记录两种标记:区间赋值和翻转,规定标记的执行顺序为先翻转再赋值,下放时就先赋值再翻转,如果一个区间被赋值,那就能覆盖之前的翻转操作,所以规定这样的顺序。新的赋值操作可以直接覆盖原来的赋值操作,而多次翻转操作应该把翻转标记取异或。

解决了这些,似乎就是一个傻题了……

【代码】

果然我还是数据结构写得太少了_(:зゝ∠)_

http://paste.ubuntu.com/10607124/

评论

© OI技术宅 | Powered by LOFTER