题目连接:hdu 3911 Black And White

题目大意:给定一个序列,然后有M次操作;

  • 0 l r:表示询问l,r中最大连续1的个数
  • 1 l r:表示将l,r区间上的数取反

解题思路:线段树的一种题型,区间合并,由于有一个取反的操作,所以对于每一个节点要维护6个值,包含连续0,1最长序列的长度,左边和右边的最长连续长度。须要注意的是,假设询问的区间最大值是从R[lson] + L[rson]来到,要推断是否比长度大于r - l + 1。一開始没注意,所以WA了,上网搜了下别人的题解,发现非常多人在query里面没有pushup更新当前节点信息,这样肯定是不行的,有pushdown,肯定要在更新当前节点信息的。

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <algorithm>
  4. using namespace std;
  5. const int maxn = 1e5 + 5;
  6. int N, M, a[maxn];
  7. #define lson(x) ((x)<<1)
  8. #define rson(x) (((x)<<1)|1)
  9. int lc[maxn << 2], rc[maxn << 2], filp[maxn << 2];
  10. int L[maxn << 2][2], R[maxn << 2][2], S[maxn << 2][2];
  11. void maintain (int u) {
  12. filp[u] ^= 1;
  13. swap(L[u][0], L[u][1]);
  14. swap(R[u][0], R[u][1]);
  15. swap(S[u][0], S[u][1]);
  16. }
  17. void pushup(int u) {
  18. for (int i = 0; i < 2; i++) {
  19. S[u][i] = max(max(S[lson(u)][i], S[rson(u)][i]), R[lson(u)][i] + L[rson(u)][i]);
  20. L[u][i] = L[lson(u)][i] + (L[lson(u)][i] == rc[lson(u)] - lc[lson(u)] + 1 ? L[rson(u)][i] : 0);
  21. R[u][i] = R[rson(u)][i] + (R[rson(u)][i] == rc[rson(u)] - lc[rson(u)] + 1 ? R[lson(u)][i] : 0);
  22. }
  23. }
  24. void pushdown (int u) {
  25. if (filp[u]) {
  26. maintain(lson(u));
  27. maintain(rson(u));
  28. filp[u] = 0;
  29. }
  30. }
  31. void build (int u, int l, int r) {
  32. lc[u] = l;
  33. rc[u] = r;
  34. filp[u] = 0;
  35. if (l == r) {
  36. int d = a[l];
  37. L[u][d] = R[u][d] = S[u][d] = 1;
  38. L[u][d^1] = R[u][d^1] = S[u][d^1] = 0;
  39. return ;
  40. }
  41. int mid = (l + r) / 2;
  42. build(lson(u), l, mid);
  43. build(rson(u), mid+1, r);
  44. pushup(u);
  45. }
  46. void modify (int u, int l, int r) {
  47. if (l <= lc[u] && rc[u] <= r) {
  48. maintain(u);
  49. return;
  50. }
  51. pushdown(u);
  52. int mid = (lc[u] + rc[u]) / 2;
  53. if (l <= mid)
  54. modify(lson(u), l, r);
  55. if (r > mid)
  56. modify(rson(u), l, r);
  57. pushup(u);
  58. }
  59. int query (int u, int l, int r) {
  60. if (l <= lc[u] && rc[u] <= r)
  61. return S[u][1];
  62. pushdown(u);
  63. int mid = (lc[u] + rc[u]) / 2, ret;
  64. if (r <= mid)
  65. ret = query(lson(u), l, r);
  66. else if (l > mid)
  67. ret = query(rson(u), l, r);
  68. else {
  69. int ll = query(lson(u), l, r);
  70. int rr = query(rson(u), l, r);
  71. int a = min(L[rson(u)][1], r - mid);
  72. int b = min(R[lson(u)][1], mid - l + 1);
  73. ret = max( max(ll, rr), a + b);
  74. }
  75. pushup(u);
  76. return ret;
  77. }
  78. int main () {
  79. int x, l, r;
  80. while (scanf("%d", &N) == 1) {
  81. for (int i = 1; i <= N; i++)
  82. scanf("%d", &a[i]);
  83. build (1, 1, N);
  84. scanf("%d", &M);
  85. while (M--) {
  86. scanf("%d%d%d", &x, &l, &r);
  87. if (x)
  88. modify(1, l, r);
  89. else
  90. printf("%d\n", query(1, l, r));
  91. }
  92. }
  93. return 0;
  94. }

hdu 3911 Black And White(线段树)的更多相关文章

  1. HDU 3911 Black and White (线段树,区间翻转)

      [题目地址] vjudge HDU [题目大意] 海滩上有一堆石头. 石头的颜色是白色或黑色. 小肥羊拥有魔术刷,她可以改变连续石的颜色,从黑变白,从白变黑. 小肥羊非常喜欢黑色,因此她想知道范围 ...

  2. HDU 3911 Black And White (线段树区间合并 + lazy标记)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3911 给你n个数0和1,m个操作: 0操作  输出l到r之间最长的连续1的个数 1操作  将l到r之间 ...

  3. HDU 3911 Black And White 分段树 题解

    Problem Description There are a bunch of stones on the beach; Stone color is white or black. Little ...

  4. HDU 3016 Man Down (线段树+dp)

    HDU 3016 Man Down (线段树+dp) Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Ja ...

  5. HDU.5692 Snacks ( DFS序 线段树维护最大值 )

    HDU.5692 Snacks ( DFS序 线段树维护最大值 ) 题意分析 给出一颗树,节点标号为0-n,每个节点有一定权值,并且规定0号为根节点.有两种操作:操作一为询问,给出一个节点x,求从0号 ...

  6. HDU.1556 Color the ball (线段树 区间更新 单点查询)

    HDU.1556 Color the ball (线段树 区间更新 单点查询) 题意分析 注意一下pushdown 和 pushup 模板类的题还真不能自己套啊,手写一遍才行 代码总览 #includ ...

  7. HDU.1166 敌兵布阵 (线段树 单点更新 区间查询)

    HDU.1166 敌兵布阵 (线段树 单点更新 区间查询) 题意分析 加深理解,重写一遍 代码总览 #include <bits/stdc++.h> #define nmax 100000 ...

  8. HDU.1394 Minimum Inversion Number (线段树 单点更新 区间求和 逆序对)

    HDU.1394 Minimum Inversion Number (线段树 单点更新 区间求和 逆序对) 题意分析 给出n个数的序列,a1,a2,a3--an,ai∈[0,n-1],求环序列中逆序对 ...

  9. HDU.1689 Just a Hook (线段树 区间替换 区间总和)

    HDU.1689 Just a Hook (线段树 区间替换 区间总和) 题意分析 一开始叶子节点均为1,操作为将[L,R]区间全部替换成C,求总区间[1,N]和 线段树维护区间和 . 建树的时候初始 ...

随机推荐

  1. POJ1163 The Triangle 【DP】

    The Triangle Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 36918   Accepted: 22117 De ...

  2. Google是不是真的不能用了?非常奇怪的问题

    这几天,事实上是这一阵子. 我连用goagent都无法上google了. 可怜我一直用Gmail邮箱.但如今我连用代理都上不了Gmail了. .. 是我自己电脑本身的问题吗?非常奇怪的问题,我原先用g ...

  3. IOS开发-表视图LV3导航控制器

    学到这里感觉有点难了,其实这篇文章再草稿箱里放了好久了~ 最近对于学习的热情下降了.这不行-抓紧学习走起! 在这一章节的学习中主要针对导航控制器及表视图来建立多视图的应用, 首先要了解一些概念-- 1 ...

  4. 【原创】poj ----- 1182 食物链 解题报告

    题目地址: http://poj.org/problem?id=1182 题目内容: 食物链 Time Limit: 1000MS   Memory Limit: 10000K Total Submi ...

  5. C++程序代写实现HashSet class

    C++程序代写实现HashSet class 专业程序代写(QQ:928900200) Implement a HashSet class for elements of type string.It ...

  6. C++习题 对象转换

    [Submit][Status][Web Board] Description 定义一个Teacher(教师)类(教师号,姓名,性别,薪金)和一个Student(学生)类(学号,姓名,性别,成绩),二 ...

  7. trie + 长度优先匹配,生成串

    import com.google.common.collect.Maps; import java.util.Map; /** * tree 节点 * Created by shuly on 16- ...

  8. OpenCV在MFC图像控件内显示图像

    1.依照文章<OpenCV+MFC显示图像>,完毕配置. 2.创建对应的图像控件,button控件. 3.进行类型转换. 在当前OpenCV2版本号内,图像格式为cv::Mat ,而该格式 ...

  9. Web Service简单入门示例

    Web Service简单入门示例     我们一般实现Web Service的方法有非常多种.当中我主要使用了CXF Apache插件和Axis 2两种. Web Service是应用服务商为了解决 ...

  10. UVA434 - Matty&#39;s Blocks

    option=com_onlinejudge&Itemid=8&page=show_problem&category=457&problem=375&mosms ...