http://acm.hust.edu.cn/vjudge/problem/14689

三个操作

  1. [a,b]覆盖为0
  2. [a,b]覆盖为1
  3. [a,b]颠倒每项

两个查询

  1. [a,b]间1数量
  2. [a,b]间最长连续1数量

其实是区间覆盖,区间颠倒和区间合并的结合,可以先看这几道题

区间合并:http://www.cnblogs.com/qlky/p/5745065.html

区间更新(两种更新方式):http://www.cnblogs.com/qlky/p/5737676.html

可以分为两项做:

1的数量很简单,用len[]保存每个区间数量即可

[a,b]区间内最长连续其实之前没做过,具体做法是:

在区间合并的基础上,在query时取左子树,右子树以及min(mid-L+1,rsum[ls])+min(R-mid,lsum[rs])的最小值

这里的min(mid-L+1,rsum[ls])+min(R-mid,lsum[rs])其实就是左子树的右端和右子树左端结合,前面那项是为了限定左右的最大值,因为要在选定的区间内找连续值

  1. #include <iostream>
  2. #include <string>
  3. #include <cstring>
  4. #include <cstdlib>
  5. #include <cstdio>
  6. #include <cmath>
  7. #include <algorithm>
  8. #include <stack>
  9. #include <queue>
  10. #include <cctype>
  11. #include <vector>
  12. #include <iterator>
  13. #include <set>
  14. #include <map>
  15. #include <sstream>
  16. using namespace std;
  17.  
  18. #define mem(a,b) memset(a,b,sizeof(a))
  19. #define pf printf
  20. #define sf scanf
  21. #define spf sprintf
  22. #define pb push_back
  23. #define debug printf("!\n")
  24. #define MAXN 100000+5
  25. #define MAX(a,b) a>b?a:b
  26. #define blank pf("\n")
  27. #define LL long long
  28. #define ALL(x) x.begin(),x.end()
  29. #define INS(x) inserter(x,x.begin())
  30. #define pqueue priority_queue
  31. #define INF 0x3f3f3f3f
  32.  
  33. #define ls (rt<<1)
  34. #define rs (rt<<1|1)
  35.  
  36. int n,m;
  37.  
  38. int col[MAXN<<],a[MAXN<<],len[MAXN<<];
  39.  
  40. int sum[MAXN<<],lsum[MAXN<<],rsum[MAXN<<],mz[MAXN<<],lz[MAXN<<],rz[MAXN<<];
  41.  
  42. void cg(int &a,int &b)
  43. {
  44. int tmp = a;
  45. a = b;
  46. b = tmp;
  47. }
  48.  
  49. void FXOR(int rt,int k)
  50. {
  51. //pf("xor%d %d %d %d t%d %d %d\n",rt,sum[rt],lsum[rt],rsum[rt],mz[rt],lz[rt],rz[rt]);
  52. //统计1数量
  53. len[rt] = k-len[rt];
  54.  
  55. //最长连续1
  56. cg(sum[rt],mz[rt]);
  57. cg(lsum[rt],lz[rt]);
  58. cg(rsum[rt],rz[rt]);
  59. //pf("xor%d %d %d %d t%d %d %d\n",rt,sum[rt],lsum[rt],rsum[rt],mz[rt],lz[rt],rz[rt]);
  60. if(a[rt]!= -)
  61. {
  62. a[rt]^=;
  63. }
  64. else col[rt]^=;
  65. }
  66.  
  67. void PushDown(int rt,int l,int r)
  68. {
  69. if(l==r) return;
  70. int mid = (l+r)>>;
  71. if(a[rt]!=-)
  72. {
  73. //统计1数量
  74. a[ls] = a[rt]?a[rt]:;
  75. a[rs] = a[rt]?a[rt]:;
  76. len[rs] = a[rt]?(r-mid):;
  77. len[ls] = a[rt]?(mid-l+):;
  78. //最长连续1
  79. sum[rs] = lsum[rs] = rsum[rs] = a[rt]?(r-mid):;
  80. sum[ls] = lsum[ls] = rsum[ls] = a[rt]?(mid-l+):;
  81. mz[rs] = lz[rs] = rz[rs] = a[rt]?:(r-mid);
  82. mz[ls] = lz[ls] = rz[ls] = a[rt]?:(mid-l+);
  83.  
  84. col[rt] = ;
  85. a[rt] = -;
  86. }
  87. if(col[rt])
  88. {
  89. if(l!=r)
  90. {
  91. FXOR(ls,mid-l+);
  92. FXOR(rs,r-mid);
  93. }
  94. col[rt] = ;
  95. }
  96. }
  97.  
  98. void PushUp(int rt,int k)
  99. {
  100. if(k==) return;
  101. //最长连续1
  102. lsum[rt] = lsum[ls];
  103. lz[rt] = lz[ls];
  104. rsum[rt] = rsum[rs];
  105. rz[rt] = rz[rs];
  106. if(lsum[rt]==k-(k>>)) lsum[rt]+=lsum[rs];
  107. if(rsum[rt]==k>>) rsum[rt]+=rsum[ls];
  108. if(lz[rt]==k-(k>>)) lz[rt]+=lz[rs];
  109. if(rz[rt]==k>>) rz[rt]+=rz[ls];
  110. sum[rt] = max(lsum[rs]+rsum[ls],max(sum[rs],sum[ls]));
  111. mz[rt] = max(lz[rs]+rz[ls],max(mz[rs],mz[ls]));
  112. //统计1数量
  113. len[rt] = len[rs]+len[ls];
  114. }
  115.  
  116. void build(int l,int r,int rt)
  117. {
  118. a[rt] = -;
  119. sum[rt] = lsum[rt] = rsum[rt] = len[rt] = col[rt] = ;
  120. mz[rt] = lz[rt] = rz[rt] = r-l+;
  121. if(l==r) return;
  122. int mid = (l+r)>>;
  123. build(l,mid,ls);
  124. build(mid+,r,rs);
  125. }
  126.  
  127. void update(int val,int L,int R,int l,int r,int rt)
  128. {
  129. if(L<=l && r<=R)
  130. {
  131. if(val==)
  132. {
  133. //统计1数量
  134. len[rt] = a[rt] = col[rt] = ;
  135.  
  136. //统计最长连续1
  137. sum[rt] = rsum[rt] = lsum[rt] = ;
  138. mz[rt] = rz[rt] = lz[rt] = r-l+;
  139. }
  140. else if(val==)
  141. {
  142. //统计1数量
  143. len[rt] = r-l+;
  144. a[rt] = ;
  145. col[rt] = ;
  146.  
  147. //统计最长连续1
  148. sum[rt] = rsum[rt] = lsum[rt] = r-l+;
  149. mz[rt] = rz[rt] = lz[rt] = ;
  150. }
  151. else
  152. {
  153. FXOR(rt,r-l+);
  154. }
  155. return;
  156. }
  157. PushDown(rt,l,r);
  158. int mid = (l+r)>>;
  159. if(L <= mid) update(val,L,R,l,mid,ls);
  160. if(R > mid) update(val,L,R,mid+,r,rs);
  161. PushUp(rt,r-l+);
  162. }
  163.  
  164. LL ans = ;
  165.  
  166. //统计1数量
  167. void query(int L,int R,int l,int r,int rt)
  168. {
  169. //pf("%d %d %d %d\n",L,R,l,r);
  170. if(L <= l && r <= R)
  171. {
  172. ans+=len[rt];
  173. return;
  174. }
  175. PushDown(rt,l,r);
  176. int mid = (l+r)>>;
  177. if(L<=mid) query(L,R,l,mid,ls);
  178. if(R>mid) query(L,R,mid+,r,rs);
  179. }
  180.  
  181. //最长连续1
  182. int query2(int L,int R,int l,int r,int rt)
  183. {
  184. //pf("%d %d %d %d\n",L,R,l,r);
  185. if(L <= l && r <= R)
  186. {
  187. return sum[rt];
  188. }
  189. PushDown(rt,l,r);
  190. int res = ;
  191. int mid = (l+r)>>;
  192. if(L<=mid)
  193. {
  194. int tmp = query2(L,R,l,mid,ls);
  195. res = max(tmp,res);
  196. }
  197. if(R>mid)
  198. {
  199. int tmp = query2(L,R,mid+,r,rs);
  200. res = max(tmp,res);
  201. }
  202. res = max(res,min(mid-L+,rsum[ls])+min(R-mid,lsum[rs]));
  203. return res;
  204. }
  205.  
  206. int main()
  207. {
  208. int n,i,j,t,kase=;
  209. sf("%d",&t);
  210. while(t--)
  211. {
  212. sf("%d%d",&n,&m);
  213. build(,n,);
  214. for(i=;i<=n;i++)
  215. {
  216. int tmp;
  217. sf("%d",&tmp);
  218. update(tmp,i,i,,n,);
  219. }
  220. //for(i=1;i<=18;i++) pf("t%d %d %d %d\n",i,sum[i],lsum[i],rsum[i]);
  221. //for(i=1;i<=18;i++) pf("t%d %d %d %d\n",i,mz[i],lz[i],rz[i]);
  222. for(i=;i<=m;i++)
  223. {
  224. int tmp,c,d;
  225. sf("%d%d%d",&tmp,&c,&d);
  226. if(tmp==) update(,c+,d+,,n,);
  227. else if (tmp==) update(,c+,d+,,n,);
  228. else if(tmp==) update(,c+,d+,,n,);
  229. else if(tmp==)
  230. {
  231. ans = ;
  232. query(c+,d+,,n,);
  233. pf("%I64d\n",ans);
  234. }
  235. else
  236. {
  237. pf("%d\n",query2(c+,d+,,n,));
  238. }
  239. //for(j=1;j<=18;j++) pf("t%d %d %d %d t%d %d\n",j,sum[j],lsum[j],rsum[j],a[j],col[j]);
  240. //for(j=1;j<=18;j++) pf("tt%d %d %d %d\n",j,mz[j],lz[j],rz[j]);
  241. }
  242. }
  243. return ;
  244. }
  245. /*
  246. 1
  247. 10 1000
  248. 0 0 0 1 1 0 1 0 1 1
  249. 3 0 0
  250. 3 1 1
  251. 3 2 2
  252. 3 3 3
  253. 3 4 4
  254. 3 5 5
  255. 3 6 6
  256. 3 7 7
  257. 3 8 8
  258. 3 9 9
  259. 3 0 0
  260. 3 0 1
  261. 3 0 2
  262. 3 0 3
  263. 3 0 4
  264. 3 0 5
  265. 3 0 6
  266. 3 0 7
  267. 3 0 8
  268. 3 0 9
  269. */

HDU 3397 区间覆盖,颠倒,合并(好题)的更多相关文章

  1. 贪心算法----区间覆盖问题(POJ2376)

    题目: 题目的大概意思是约翰这个农民有N条牛,这些牛可以在一天中的某个时间段可以进行工作,他想把这个时间段分成若干个片段让这些牛去进行打扫任务,你的任务是安排尽量少的牛然后可以完成分成这些片段的打扫任 ...

  2. UVA 10382 Watering Grass(区间覆盖,贪心)题解

    题意:有一块草坪,这块草坪长l 米,宽 w 米,草坪有一些喷头,每个喷头在横坐标为 p 处,每个喷头的纵坐标都是(w/2) ,并且喷头的洒水范围是一个以喷头为圆心,半径为 r 米的圆.每次最少需要打开 ...

  3. POJ 3667 & HDU 3308 & HDU 3397 线段树的区间合并

    看到讲课安排上 线段树有一节课"区间合并" 我是迷茫的 因为并没有见过 然后了解了一下题目 发现以前写过 还是很麻烦的树链剖分 大概是 解决带修改的区间查询"连续问题&q ...

  4. (简单) HDU 3397 Sequence operation,线段树+区间合并。

    Problem Description lxhgww got a sequence contains n characters which are all '0's or '1's. We have ...

  5. HDU 4509 湫湫系列故事——减肥记II(线段树-区间覆盖 或者 暴力技巧)

    http://acm.hdu.edu.cn/showproblem.php?pid=4509 题目大意: 中文意义,应该能懂. 解题思路: 因为题目给的时间是一天24小时,而且还有分钟.为了解题方便, ...

  6. 2016 Multi-University Training Contest 10 [HDU 5861] Road (线段树:区间覆盖+单点最大小)

    HDU 5861 题意 在n个村庄之间存在n-1段路,令某段路开放一天需要交纳wi的费用,但是每段路只能开放一次,一旦关闭将不再开放.现在给你接下来m天内的计划,在第i天,需要对村庄ai到村庄bi的道 ...

  7. Tunnel Warfare HDU 1540 区间合并+最大最小值

    Tunnel Warfare HDU 1540 区间合并+最大最小值 题意 D x是破坏这个点,Q x是表示查询以x所在的最长的连续的点的个数,R是恢复上一次破坏的点. 题解思路 参考的大佬博客 这里 ...

  8. 牛客挑战赛40 VMware和基站 set 二分 启发式合并 区间覆盖

    LINK:VMware和基站 一道 做法并不常见的题目 看起来很难写 其实set维护线段就可以解决了. 容易想到 第二个操作借用启发式合并可以得到一个很不错的复杂度 不过利用线段树维护这个东西 在区间 ...

  9. HDU - 3974 Assign the task (DFS建树+区间覆盖+单点查询)

    题意:一共有n名员工, n-1条关系, 每次给一个人分配任务的时候,(如果他有)给他的所有下属也分配这个任务, 下属的下属也算自己的下属, 每次查询的时候都输出这个人最新的任务(如果他有), 没有就输 ...

随机推荐

  1. opencv学习笔记2

    import cv2 as cvimport numpy as np"""#图像加法运算 即像素加法 (结果图=图1+图二) (两个图像必须是等大等类型的)image = ...

  2. VSLAM技术框架详述

    最早的SLAM雏形是在军事(核潜艇的海底定位)上的应用,主要传感器是军用雷达.SLAM技术发展到如今已经几十年,目前以激光雷达作为主传感器的SLAM技术比较稳定.可靠,仍然是主流的技术方案.但随着最近 ...

  3. EasyUI学习笔记(四)—— datagrid的使用

    一.传统的HTML表格 之前我们做表格的时候是这样写的: <table > <thead> <tr> <th>编号</th> <th& ...

  4. C++ STL之Vector

    向量 vector 是一种对象实体, 能够容纳许多其他类型相同的元素, 因此又被称为容器. vector 属于STL(Standard Template Library, 标准模板库)中的一种自定义的 ...

  5. python爬虫之User-Agent用户信息

    python爬虫之User-Agent用户信息 爬虫是自动的爬取网站信息,实质上我们也只是一段代码,并不是真正的浏览器用户,加上User-Agent(用户代理,简称UA)信息,只是让我们伪装成一个浏览 ...

  6. TensorFlow-简单的卷积神经网络

    先弄懂卷积神经网络的原理,推荐这两篇博客:http://blog.csdn.net/yunpiao123456/article/details/52437794   http://blog.csdn. ...

  7. 利用Flume将本地文件数据中收集到HDFS

    1. 创建文件 放入一个txt文件 然后查看hdfs上的文件夹 不知道为什么并没有出现本地的文件 也不报错 后来发现,没有在logs文件夹下面,在newlogs文件夹下面

  8. Python学习 day03

    一.基本数据类型 python中的基本数据类型有以下几种: int   --  整数     python3中默认整数都是int型,python2中int的范围为-231~232-1(32位系统中)/ ...

  9. Centos 7 如何卸载docker

    1.[root@localhost ~]# rpm -qa|grep docker docker.x86_64 2:1.12.6-16.el7.centos @extras docker-client ...

  10. (转)模块readline解析

    模块readline解析 原文:https://www.cnblogs.com/fireflow/p/4841413.html readline模块定义了一系列函数用来读写Python解释器中历史命令 ...