题意:给你一些区间操作,让你输出最后得出的区间。

解法:区间操作的经典题,借鉴了网上的倍增算法,每次将区间乘以2,然后根据区间开闭情况做微调,这样可以有效处理开闭区间问题。

线段树维护两个值: cov 和 rev  ,一个是覆盖标记,0表示此区间被0覆盖,1表示被1覆盖,-1表示未被覆盖, rev为反转标记,rev = 1表示反转,0表示不翻转

所以集合操作可以化为如下区间操作:

U l r:   把区间[l,r]覆盖成1
I  l r:   把[0,l)(r,MAX]覆盖成0
D l r:   把区间[l,r]覆盖成0
C l r:   把[0,l)(r,MAX]覆盖成0 , 且[l,r]区间0/1互换
S l r:   [l,r]区间0/1互换

重点在于pushdown函数以及边界处理。

代码:

  1. #include <iostream>
  2. #include <cmath>
  3. #include <iostream>
  4. #include <cstdio>
  5. #include <cstring>
  6. #include <cstdlib>
  7. #include <cmath>
  8. #include <algorithm>
  9. using namespace std;
  10. #define N (65536*2)
  11.  
  12. struct Tree
  13. {
  14. int cov,rev; //cov -1 rev 0
  15. }tree[*N];
  16.  
  17. struct ANS
  18. {
  19. char L,R;
  20. int A,B;
  21. }ans[N+];
  22. int cnt;
  23.  
  24. void build(int l,int r,int rt)
  25. {
  26. tree[rt].cov = ;
  27. tree[rt].rev = ;
  28. if(l == r) return;
  29. int mid = (l+r)/;
  30. build(l,mid,*rt);
  31. build(mid+,r,*rt+);
  32. }
  33.  
  34. void pushdown(int l,int r,int rt)
  35. {
  36. if(tree[rt].cov != -)
  37. {
  38. tree[*rt].cov = tree[*rt+].cov = tree[rt].cov;
  39. tree[*rt].rev = tree[*rt+].rev = ;
  40. tree[rt].cov = -;
  41. }
  42. if(tree[rt].rev)
  43. {
  44. if(tree[*rt].cov != -)
  45. tree[*rt].cov ^= ;
  46. else
  47. tree[*rt].rev ^= ;
  48.  
  49. if(tree[*rt+].cov != -)
  50. tree[*rt+].cov ^= ;
  51. else
  52. tree[*rt+].rev ^= ;
  53. tree[rt].rev = ;
  54. }
  55. }
  56.  
  57. void update(int l,int r,int aa,int bb,int op,int rt)
  58. {
  59. if(aa > bb || aa < ) return; //必须要加,否则会RE
  60. if(aa <= l && bb >= r)
  61. {
  62. if(op != ) //cover to 0/1
  63. {
  64. tree[rt].cov = op;
  65. tree[rt].rev = ;
  66. }
  67. else //op == 2 reverse
  68. {
  69. if(tree[rt].cov != -)
  70. tree[rt].cov ^= ;
  71. else
  72. tree[rt].rev ^= ;
  73. }
  74. return;
  75. }
  76. pushdown(l,r,rt);
  77. int mid = (l+r)/;
  78. if(aa <= mid)
  79. update(l,mid,aa,bb,op,*rt);
  80. if(bb > mid)
  81. update(mid+,r,aa,bb,op,*rt+);
  82. }
  83.  
  84. void query(int l,int r,int rt)
  85. {
  86. if(tree[rt].cov == )
  87. {
  88. ans[cnt].L = (l%==)?'(':'[';
  89. ans[cnt].A = l/;
  90. ans[cnt].R = (r%==)?')':']';
  91. ans[cnt].B = (r+)/;
  92. cnt++;
  93. }
  94. else if(tree[rt].cov == ) return;
  95. else
  96. {
  97. pushdown(l,r,rt);
  98. int mid = (l+r)/;
  99. query(l,mid,*rt);
  100. query(mid+,r,*rt+);
  101. }
  102. }
  103.  
  104. void print()
  105. {
  106. char nowl,nowr;
  107. int nowA,nowB;
  108. if(cnt == )
  109. puts("empty set");
  110. else
  111. {
  112. nowl = ans[].L;
  113. nowr = ans[].R;
  114. nowA = ans[].A;
  115. nowB = ans[].B;
  116. for(int i=;i<cnt;i++)
  117. {
  118. if(ans[i].A == nowB && (nowr == ']' || ans[i].L == '['))
  119. {
  120. nowB = ans[i].B;
  121. nowr = ans[i].R;
  122. }
  123. else
  124. {
  125. printf("%c%d,%d%c ",nowl,nowA,nowB,nowr);
  126. nowl = ans[i].L;
  127. nowr = ans[i].R;
  128. nowA = ans[i].A;
  129. nowB = ans[i].B;
  130. }
  131. }
  132. printf("%c%d,%d%c\n",nowl,nowA,nowB,nowr);
  133. }
  134. }
  135.  
  136. int main()
  137. {
  138. int a,b;
  139. char L,R,op;
  140. int n = *;
  141. build(,n,);
  142. while(scanf("%c %c%d,%d%c\n",&op,&L,&a,&b,&R)!=EOF) // '\n' 务必要加
  143. {
  144. a = *a; if(L == '(') a++;
  145. b = *b; if(R == ')') b--;
  146. if(a > b || a < ) continue;
  147. if(op == 'U') //并集
  148. update(,n,a,b,,);
  149. else if(op == 'I')
  150. {
  151. update(,n,,a-,,);
  152. update(,n,b+,n,,);
  153. }
  154. else if(op == 'D')
  155. update(,n,a,b,,);
  156. else if(op == 'C')
  157. {
  158. update(,n,,a-,,);
  159. update(,n,b+,n,,);
  160. update(,n,a,b,,);
  161. }
  162. else
  163. update(,n,a,b,,);
  164. }
  165. cnt = ;
  166. query(,n,);
  167. print();
  168. return ;
  169. }

参考文章: http://my.oschina.net/llmm/blog/124256

POJ 3225 Help with Intervals --线段树区间操作的更多相关文章

  1. poj 3225 Help with Intervals(线段树,区间更新)

    Help with Intervals Time Limit: 6000MS   Memory Limit: 131072K Total Submissions: 12474   Accepted:  ...

  2. (中等) POJ 3225 Help with Intervals , 线段树+集合。

    Description LogLoader, Inc. is a company specialized in providing products for analyzing logs. While ...

  3. POJ.2528 Mayor's posters (线段树 区间更新 区间查询 离散化)

    POJ.2528 Mayor's posters (线段树 区间更新 区间查询 离散化) 题意分析 贴海报,新的海报能覆盖在旧的海报上面,最后贴完了,求问能看见几张海报. 最多有10000张海报,海报 ...

  4. POJ 2528 Mayor's posters (线段树区间更新+离散化)

    题目链接:http://poj.org/problem?id=2528 给你n块木板,每块木板有起始和终点,按顺序放置,问最终能看到几块木板. 很明显的线段树区间更新问题,每次放置木板就更新区间里的值 ...

  5. POJ 2528 ——Mayor's posters(线段树+区间操作)

    Time limit 1000 ms Memory limit 65536 kB Description The citizens of Bytetown, AB, could not stand t ...

  6. Bzoj 1798: [Ahoi2009]Seq 维护序列seq(线段树区间操作)

    1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec Memory Limit: 64 MB Description 老师交给小可可一个维护数列的任务,现在小可 ...

  7. 线段树(区间操作) POJ 3325 Help with Intervals

    题目传送门 题意:四种集合的操作,对应区间的01,问最后存在集合存在的区间. 分析:U T [l, r]填充1; I T [0, l), (r, N]填充0; D T [l, r]填充0; C T[0 ...

  8. poj 2528 Mayor's posters 线段树区间更新

    Mayor's posters Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://poj.org/problem?id=2528 Descript ...

  9. hdu 1540/POJ 2892 Tunnel Warfare 【线段树区间合并】

    Tunnel Warfare                                                             Time Limit: 4000/2000 MS ...

随机推荐

  1. 清除浮动after

    .clearf{display: inline-block;} .clearf:after { content: "."; display: block; height:; cle ...

  2. HTML · 图片热点,网页划区,拼接,表单

    图片热点: 规划出图片上的一个区域,可以做出超链接,直接点击图片区域就可以完成跳转的效果. 网页划区: 在一个网页里,规划出一个区域用来展示另一个网页的内容. 网页的拼接: 在一个网络页面内,规划出多 ...

  3. 再说Play!framework http://hsfgo.iteye.com/blog/806974

    这篇帖子的内容我本来想发到 http://www.iteye.com/topic/806660这里的主贴里去的,想挽回被隐藏的命运,但我写完本贴的内容,却发现为时已晚.好吧,我承认,上一个贴的标题容易 ...

  4. OC正则表达式的使用

    OC中一般正则表达式的使用方法为2步 1.创建一个正则表达式对象 2.利用正则表达式来测试对应的字符串 例如 NSString *checkString = @"a34sd231" ...

  5. 关于UI资源获取资源的好的网站

    前言:和我一样喜欢UI的一定喜欢这里的内容. 下面是关于sketch资源获取网页,点击图片就能进入: 连接是:https://github.com/JakeLin 居然意外百度到Sketch中国,还提 ...

  6. Objective-C之代理设计模式小实例

    *:first-child { margin-top: 0 !important; } body > *:last-child { margin-bottom: 0 !important; } ...

  7. Swift 中的函数(下)

    学习来自<极客学院:Swift中的函数> 工具:Xcode6.4 直接上基础的示例代码,多敲多体会就会有收获:百看不如一敲,一敲就会 import Foundation /******** ...

  8. mysql给数据库授权 GRANT ALL PRIVILEGES ON

    mysql> grant 权限1,权限2,…权限n on 数据库名称.表名称 to 用户名@用户地址 identified by ‘连接口令’; show grants for mustang@ ...

  9. Effective Java 60 Favor the use of standard exceptions

    Benefits to reuse preexisting exceptions It makes your API easier to learn and use. Programs using y ...

  10. http://runjs.cn/

    http://runjs.cn/ RunJS - 在线编辑.展示.分享.交流你的 JavaScript 代码