线段树的应用,很不错的一道题目。结点属性包括:
(1)n1:1的个数;
(2)c1:连续1的最大个数;
(3)c0:连续0的最大个数;
(4)lc1/lc0:从区间左边开始,连续1/0的最大个数;
(5)rc1/rc0:从区间右边开始,连续1/0的最大个数;
(6)set:置区间为0/1的标记;
(7)flip:0->1, 1->0的标记。
采用延迟更新。每当更新set时,flip就置为false;每当更新flip时,其实就是c1/c0, lc1/lc0, rc1/rc0的交换。
对于询问最长连续1,共包括3种情况:左子树的最长连续1,右子树的最长连续1,以及左子树rc1+右子树lc1(注意有效范围区间)。

  1. /* 3397 */
  2. #include <iostream>
  3. #include <string>
  4. #include <map>
  5. #include <queue>
  6. #include <set>
  7. #include <vector>
  8. #include <algorithm>
  9. #include <cstdio>
  10. #include <cmath>
  11. #include <cstring>
  12. #include <climits>
  13. #include <cctype>
  14. using namespace std;
  15.  
  16. #define MAXN 100005
  17. #define lson l, mid, rt<<1
  18. #define rson mid+1, r, rt<<1|1
  19.  
  20. typedef struct {
  21. int set;
  22. int n1;
  23. int c1, c0;
  24. int lc1, lc0, rc1, rc0;
  25. bool flip;
  26. } node_t;
  27.  
  28. node_t nd[MAXN<<];
  29. int t, n, m, x;
  30. int op;
  31.  
  32. void maintance_set(int op, int len, int rt) {
  33. nd[rt].set = op;
  34. nd[rt].flip = false;
  35. if (op) {
  36. nd[rt].n1 = nd[rt].c1 = nd[rt].lc1 = nd[rt].rc1 = len;
  37. nd[rt].c0 = nd[rt].lc0 = nd[rt].rc0 = ;
  38. } else {
  39. nd[rt].n1 = nd[rt].c1 = nd[rt].lc1 = nd[rt].rc1 = ;
  40. nd[rt].c0 = nd[rt].lc0 = nd[rt].rc0 = len;
  41. }
  42. }
  43.  
  44. void maintance_flip(int len, int rt) {
  45. if (nd[rt].set >= )
  46. nd[rt].set = !nd[rt].set;
  47. else
  48. nd[rt].flip = !nd[rt].flip;
  49. nd[rt].n1 = len-nd[rt].n1;
  50. swap(nd[rt].c0, nd[rt].c1);
  51. swap(nd[rt].lc0, nd[rt].lc1);
  52. swap(nd[rt].rc0, nd[rt].rc1);
  53. }
  54.  
  55. void PushUp(int l, int r, int rt) {
  56. int lb = rt<<;
  57. int rb = rt<<|;
  58. int mid = (l+r)>>;
  59.  
  60. // update the number of 1
  61. nd[rt].n1 = nd[lb].n1 + nd[rb].n1;
  62. // update the longest continuous 1 and 0 in string
  63. nd[rt].c1 = max(
  64. max(nd[lb].c1, nd[rb].c1),
  65. nd[lb].rc1 + nd[rb].lc1
  66. );
  67. nd[rt].c0 = max(
  68. max(nd[lb].c0, nd[rb].c0),
  69. nd[lb].rc0 + nd[rb].lc0
  70. );
  71. // update the longest continuous 1/0 from left
  72. nd[rt].lc1 = nd[lb].lc1;
  73. nd[rt].lc0 = nd[lb].lc0;
  74. if (nd[lb].lc1 == mid-l+)
  75. nd[rt].lc1 += nd[rb].lc1;
  76. if (nd[lb].lc0 == mid-l+)
  77. nd[rt].lc0 += nd[rb].lc0;
  78. // update the longest continuous 1/0 from right
  79. nd[rt].rc1 = nd[rb].rc1;
  80. nd[rt].rc0 = nd[rb].rc0;
  81. if (nd[rb].rc1 == r-mid)
  82. nd[rt].rc1 += nd[lb].rc1;
  83. if (nd[rb].rc0 == r-mid)
  84. nd[rt].rc0 += nd[lb].rc0;
  85. }
  86.  
  87. void PushDown(int l, int r, int rt) {
  88. int lb = rt<<;
  89. int rb = rt<<|;
  90. int mid = (l+r)>>;
  91.  
  92. if (nd[rt].set >= ) {
  93. // maintance_set lson & rson
  94. maintance_set(nd[rt].set, mid-l+, lb);
  95. maintance_set(nd[rt].set, r-mid, rb);
  96. nd[rt].set = -;
  97. }
  98. if (nd[rt].flip) {
  99. // maintance_flip lson & rson
  100. maintance_flip(mid-l+, lb);
  101. maintance_flip(r-mid, rb);
  102. nd[rt].flip = false;
  103. }
  104. }
  105.  
  106. void build(int l, int r, int rt) {
  107. nd[rt].set = -;
  108. nd[rt].flip = false;
  109. if (l == r) {
  110. scanf("%d", &x);
  111. nd[rt].n1 = nd[rt].c1 = nd[rt].lc1 = nd[rt].rc1 = x;
  112. nd[rt].c0 = nd[rt].lc0 = nd[rt].rc0 = !x;
  113. return ;
  114. }
  115. int mid = (l+r)>>;
  116. build(lson);
  117. build(rson);
  118. PushUp(l, r, rt);
  119. }
  120.  
  121. // update to set [L, R] to op
  122. void update1(int L, int R, int l, int r, int rt) {
  123. if (L<=l && R>=r) {
  124. maintance_set(op, r-l+, rt);
  125. return ;
  126. }
  127. int mid = (l+r)>>;
  128. PushDown(l, r, rt);
  129. if (L <= mid)
  130. update1(L, R, lson);
  131. if (R > mid)
  132. update1(L, R, rson);
  133. PushUp(l, r, rt);
  134. }
  135.  
  136. // update to flip [L, R] one
  137. void update2(int L, int R, int l, int r, int rt) {
  138. if (L<=l && R>=r) {
  139. maintance_flip(r-l+, rt);
  140. return ;
  141. }
  142. int mid = (l+r)>>;
  143. PushDown(l, r, rt);
  144. if (L <= mid)
  145. update2(L, R, lson);
  146. if (R > mid)
  147. update2(L, R, rson);
  148. PushUp(l, r, rt);
  149. }
  150.  
  151. // query the sum of 1 in [L, R]
  152. int query3(int L, int R, int l, int r, int rt) {
  153. if (L<=l && R>=r)
  154. return nd[rt].n1;
  155. int mid = (l+r)>>;
  156. PushDown(l, r, rt);
  157. int ret = ;
  158. if (L <= mid)
  159. ret += query3(L, R, lson);
  160. if (R > mid)
  161. ret += query3(L, R, rson);
  162. return ret;
  163. }
  164.  
  165. // query the longest continous 1 in [L, R]
  166. int query4(int L, int R, int l, int r, int rt) {
  167. if (L<=l && R>=r)
  168. return nd[rt].c1;
  169. int mid = (l+r)>>;
  170. PushDown(l, r, rt);
  171. int ret;
  172. if (L > mid) {
  173. return query4(L, R, rson);
  174. } else if (R <= mid) {
  175. return query4(L, R, lson);
  176. } else {
  177. ret = max(
  178. query4(L, R, lson),
  179. query4(L, R, rson)
  180. );
  181. int rc1 = nd[rt<<].rc1;
  182. int lc1 = nd[rt<<|].lc1;
  183. if (rc1 > mid-L+)
  184. rc1 = mid-L+;
  185. if (lc1 > R-mid)
  186. lc1 = R-mid;
  187. ret = max(
  188. rc1 + lc1,
  189. ret
  190. );
  191. }
  192. return ret;
  193. }
  194.  
  195. int main() {
  196. int i, j, k;
  197. int a, b;
  198.  
  199. #ifndef ONLINE_JUDGE
  200. freopen("data.in", "r", stdin);
  201. freopen("data.out", "w", stdout);
  202. #endif
  203.  
  204. scanf("%d", &t);
  205. while (t--) {
  206. scanf("%d %d", &n, &m);
  207. build(, n, );
  208. while (m--) {
  209. scanf("%d %d %d", &op, &a, &b);
  210. ++a;
  211. ++b;
  212. if (op == ) {
  213. update1(a, b, , n, );
  214. } else if (op == ) {
  215. update1(a, b, , n, );
  216. } else if (op == ) {
  217. update2(a, b, , n, );
  218. } else if (op == ) {
  219. k = query3(a, b, , n, );
  220. printf("%d\n", k);
  221. } else {
  222. k = query4(a, b, , n, );
  223. printf("%d\n", k);
  224. }
  225. }
  226. }
  227.  
  228. return ;
  229. }

【HDOJ】3397 Sequence operation的更多相关文章

  1. HDU 3397 Sequence operation(线段树)

    HDU 3397 Sequence operation 题目链接 题意:给定一个01序列,有5种操作 0 a b [a.b]区间置为0 1 a b [a,b]区间置为1 2 a b [a,b]区间0变 ...

  2. 【arc071f】Infinite Sequence(动态规划)

    [arc071f]Infinite Sequence(动态规划) 题面 atcoder 洛谷 题解 不难发现如果两个不为\(1\)的数连在一起,那么后面所有数都必须相等. 设\(f[i]\)表示\([ ...

  3. 【arc074e】RGB Sequence(动态规划)

    [arc074e]RGB Sequence(动态规划) 题面 atcoder 洛谷 翻译见洛谷 题解 直接考虑暴力\(dp\),设\(f[i][j][k][l]\)表示当前考虑到第\(i\)位,最后一 ...

  4. 【BZOJ1367】[Baltic2004]sequence 左偏树

    [BZOJ1367][Baltic2004]sequence Description Input Output 一个整数R Sample Input 7 9 4 8 20 14 15 18 Sampl ...

  5. 【BZOJ3043】IncDec Sequence 乱搞

    [BZOJ3043]IncDec Sequence Description 给定一个长度为n的数列{a1,a2...an},每次可以选择一个区间[l,r],使这个区间内的数都加一或者都减一.问至少需要 ...

  6. hdu 3397 Sequence operation(很有意思的线段树题)

    Sequence operation Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Othe ...

  7. 【HDOJ】5063 Operation the Sequence

    #include <cstdio> #include <cstring> #include <cstdlib> #define MAXN 100005 #defin ...

  8. 【线段树】HDU 3397 Sequence operation 区间合并

    操作 Change operations: 0 a b change all characters into '0's in [a , b] 1 a b change all characters i ...

  9. 【HDOJ】2062 Subset sequence

    这道题目非常好,饶了点儿圈子.我的思路是,先按照组排列.例如,1            2           31 2         2 1        3 11 2 3      2 1 3  ...

随机推荐

  1. JavaScript 开发规范要求详解

    作为一名开发人员(We前端JavaScript开发),不规范的开发不仅使日后代码维护变的困难,同时也不利于团队的合作,通常还会带来代码安全以及执行效率上的问题.本人在开发工作中就曾与不按规范来开发的同 ...

  2. 关于jquery获取服务器端xml数据

    其实这个很简单,但是有时候简单的东西会让你犯一些低级错误. 今天写了个spring mvc 的服务器端接口,主要是用来共享一些数据库数据. 请求字段:http://localhost:8080/XXX ...

  3. 【原创教程】鲸吞HTML

    首先,我们的angularJS课程分为三大模块: HTML/CSS/JS基础. angularJS详解. angualrJS的一些实用框架讲解. 其中,第一大模块的对象是对前端开发技术有点了解但不熟悉 ...

  4. (转)spring ioc原理(看完后大家可以自己写一个spring)

    最近,买了本Spring入门书:spring In Action .大致浏览了下感觉还不错.就是入门了点.Manning的书还是不错的,我虽然不像哪些只看Manning书的人那样专注于Manning, ...

  5. [Excel] CsvHelper---C#关于CSV文件的导入和导出以及转化 (转载)

    点击下载 CsvHelper.rar 这个类是关于Csv文件的一些高级操作1.DataTable导出到CSV2.将Csv读入DataTable看下面代码吧 /// <summary> // ...

  6. 微信Demo导入遇到的问题

    最近做支付宝和微信接入自己APP工程的功能,遇到了一些问题,跟大家分享: 这里先说Android开发微信支付接入. 首先根据官方文档进行,对比支付宝的官方文档,微信部分更显得“摘要”一些. 导入后自行 ...

  7. Android - 广播机制和Service

    花了几天,想实现定位功能,使用的是百度的服务,有时真的很无奈,就是一小小个问题,就能折腾好几天. 首先,我是在主线程(Fragment)中单独进行定位,发现不起作用. 然后我想使用Service和广播 ...

  8. html-----005

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  9. 类库探源——System.Exception

    一.MSDN描述 Exception 类: 表示在应用程序执行期间发生的错误 命名空间 : System 程序集:   mscorlib.dll 继承关系: 常用属性(含字段)和方法: 1. 属性Me ...

  10. cocos2d-x系列 Mac下配置cocos2d-x开发环境(android和ios)

    一.下载cocos2d-x http://cocos2d-x.org/projects/cocos2d-x/wiki/Download cocos2d-x-2.1.4.zip @ June.18, 2 ...