题意

你有一个无限大的绘图板,开始颜色是\(0\) , 你将进行\(n\) 次绘图,第\(i\) 次绘图会将左下角为 \((x_1, y_1)\),右上角为\((x_2, y_2)\) 的矩形涂成颜色\(i\). 问你最后能看到的颜色数量 ( 包括 0 ).

\(n\le 10^5\)

分析

  • \(kd-tree\) 不好维护可行面积,所以考虑扫描线套线段树。

  • 我们可以给每种颜色一个权值(出现的时间)表示他被看到的难易程度,出现时间越晚的颜色越容易被看到。

  • 线段树上维护当前可以被看到的未出现的颜色中权值最大的颜色 \(Max\),每次取出根节点维护的值并打上标记,表示已经看到过。

  • 但是有可能 \(Max\) 被当前区间的某个已经出现的颜色全部遮住了,所以还需要维护标记 \(Min\) ,意义如下:

    我们记 \(mx_p\) 表示所有覆盖位置 \(p\) 的已出现权值的最大值, \(Min=\min_\limits{p\in[l,r]}\{mx_p\}\) 。

  • 再用一个 \(set​\) 维护出现在整个区间中的最大的颜色是多少,显然其他的颜色不是被他覆盖就是不能覆盖它。

  • 节点维护:

    \(Max=max({Max}_l,{Max}_r,maxv)\) ,\(maxv\) 表示出现在 \(set\) 中的最大权值(如果还没有被看到)

    \(Min=max(min({Min}_l,{Min}_r),maxv)\) ,\(maxv\) 表示出现在 \(set​\) 中的最大权值(如果已经出现了)

  • 所以如果区间的 \(Max < Min\) 表示不存在未出现的颜色可以被看到。

  • 总时间复杂度为 \(O(nlog^2n)\)。

代码

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. typedef long long LL;
  4. #define rep(i, a, b) for(int i = a; i <= b; ++i)
  5. #define pb push_back
  6. #define re(x) memset(x, 0, sizeof x)
  7. inline int gi() {
  8. int x = 0,f = 1;
  9. char ch = getchar();
  10. while(!isdigit(ch)) { if(ch == '-') f = -1; ch = getchar();}
  11. while(isdigit(ch)) { x = (x << 3) + (x << 1) + ch - 48; ch = getchar();}
  12. return x * f;
  13. }
  14. template <typename T> inline void Max(T &a, T b){if(a < b) a = b;}
  15. template <typename T> inline void Min(T &a, T b){if(a > b) a = b;}
  16. const int N = 2e5 + 7;
  17. int n, ndc, vc;
  18. int V[N], mx[N << 2], mi[N << 2], xl[N], xr[N], yl[N], yr[N];
  19. bool vis[N];
  20. #define Ls o << 1
  21. #define Rs o << 1 | 1
  22. struct qs {
  23. int p, l, r, opt;
  24. bool operator <(const qs &rhs) const {
  25. if(p != rhs.p) return p < rhs.p;
  26. return opt < rhs.opt;
  27. }
  28. }q[N];
  29. struct Heap {
  30. priority_queue<int>A, B;
  31. void ins(int x){ A.push(x);}
  32. void del(int x){ B.push(x);}
  33. int top() {
  34. while(!B.empty() && A.top() == B.top()) A.pop(), B.pop();
  35. return A.empty() ? 0 : A.top();
  36. }
  37. }col[N << 2];
  38. void pushup(int l, int r, int o) {
  39. if(l ^ r) {
  40. mi[o] = min(mi[Ls], mi[Rs]);
  41. mx[o] = max(mx[Ls], mx[Rs]);
  42. }else mi[o] = mx[o] = 0;
  43. if(col[o].top()) {
  44. int x = col[o].top();
  45. if(vis[x]) Max(mi[o], x);
  46. else Max(mx[o], x);
  47. if(mi[o] > mx[o]) mx[o] = 0;
  48. }
  49. }
  50. void modify(int L, int R, int l, int r, int o, int v) {
  51. if(L <= l && r <= R) {
  52. if(v > 0) col[o].ins(v);
  53. if(v < 0) col[o].del(-v);
  54. pushup(l, r, o);
  55. return;
  56. }int mid = l + r >> 1;
  57. if(L <= mid) modify(L, R, l, mid, Ls, v);
  58. if(R > mid) modify(L, R, mid + 1, r, Rs, v);
  59. pushup(l, r, o);
  60. }
  61. int main() {
  62. n = gi();
  63. rep(i, 1, n) {
  64. xl[i] = gi(), yl[i] = gi(), xr[i] = gi(), yr[i] = gi();
  65. q[++ndc] = (qs){ xl[i], yl[i], yr[i] - 1, i};
  66. q[++ndc] = (qs){ xr[i], yl[i], yr[i] - 1, -i};
  67. V[++vc] = yl[i];
  68. V[++vc] = yr[i];
  69. }
  70. sort(V + 1, V + 1 + vc);
  71. sort(q + 1, q + 1 + ndc);
  72. vc = unique(V + 1, V + 1 + vc) - V - 1;
  73. rep(i, 1, n) {
  74. yl[i] = lower_bound(V + 1, V + 1 + vc, yl[i]) - V;
  75. yr[i] = upper_bound(V + 1, V + 1 + vc, yr[i] - 1) - V - 1;
  76. }
  77. rep(i, 1, ndc) {
  78. q[i].l = lower_bound(V + 1, V + 1 + vc, q[i].l) - V;
  79. q[i].r = upper_bound(V + 1, V + 1 + vc, q[i].r) - V - 1;
  80. }
  81. for(int i = 1, j = 1; i <= ndc; i = j) {
  82. for(;j <= ndc && q[j].p == q[i].p; ++j)
  83. modify(q[j].l, q[j].r, 1, vc, 1, q[j].opt);
  84. while(mx[1]) {
  85. int x = mx[1];vis[x] = 1;
  86. modify(yl[x], yr[x], 1, vc, 1, 0);
  87. }
  88. }
  89. int ans = 1;
  90. rep(i, 1, n) if(vis[i]) ++ans;
  91. printf("%d\n", ans);
  92. return 0;
  93. }

[CF983D]Arkady and Rectangles[线段树+可删堆/set]的更多相关文章

  1. 【bzoj5210】最大连通子块和 树链剖分+线段树+可删除堆维护树形动态dp

    题目描述 给出一棵n个点.以1为根的有根树,点有点权.要求支持如下两种操作: M x y:将点x的点权改为y: Q x:求以x为根的子树的最大连通子块和. 其中,一棵子树的最大连通子块和指的是:该子树 ...

  2. Codeforces 524E Rooks and Rectangles 线段树

    区域安全的check方法就是, 每行都有哨兵或者每列都有哨兵,然后我们用y建线段树, 维护在每个y上的哨兵的x的最值就好啦. #include<bits/stdc++.h> #define ...

  3. [CF983D]Arkady and Rectangles

    题意:按顺序在坐标轴上画$n$个颜色为$1\cdots n$的矩形(数字大的颜色覆盖数字小的颜色),问最后能看到多少种颜色 先离散化,然后考虑扫描线+线段树 线段树每个节点用一个set存覆盖整个区间的 ...

  4. Codeforces 1163F 最短路 + 线段树 (删边最短路)

    题意:给你一张无向图,有若干次操作,每次操作会修改一条边的边权,每次修改后输出1到n的最短路.修改相互独立. 思路:我们先以起点和终点为根,找出最短路径树,现在有两种情况: 1:修改的边不是1到n的最 ...

  5. 【BZOJ 2333 】[SCOI2011]棘手的操作(离线+线段树|可并堆-左偏树)

    2333: [SCOI2011]棘手的操作 Description 有N个节点,标号从1到N,这N个节点一开始相互不连通.第i个节点的初始权值为a[i],接下来有如下一些操作: U x y: 加一条边 ...

  6. Vijos 1404 遭遇战 - 动态规划 - 线段树 - 最短路 - 堆

    背景 你知道吗,SQ Class的人都很喜欢打CS.(不知道CS是什么的人不用参加这次比赛). 描述 今天,他们在打一张叫DUSTII的地图,万恶的恐怖分子要炸掉藏在A区的SQC论坛服务器!我们SQC ...

  7. 【递归】【线段树】【堆】AtCoder Regular Contest 080 E - Young Maids

    给你一个1~n的排列p,n是偶数,每次从中任选一对相邻的数出来,插到排列q的开头,如此循环,问你所能得到的字典序最小的排列q. 我们先确定q开头的两个数q1,q2,q1一定是p的奇数位的最小的数,而q ...

  8. VK Cup 2015 - Round 1 E. Rooks and Rectangles 线段树 定点修改,区间最小值

    E. Rooks and Rectangles Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://codeforces.com/problemse ...

  9. hdu2461 Rectangles 线段树--扫描线

    You are developing a software for painting rectangles on the screen. The software supports drawing s ...

随机推荐

  1. apk安装提示:Failure [INSTALL_FAILED_DUPLICATE_PERMISSION perm=XXX]

    近日,楼主在同一台手机上,同时安装同一个游戏的不同渠道包,add install后,提示:Failure [INSTALL_FAILED_DUPLICATE_PERMISSION perm=andro ...

  2. 如何在EF Core 使用存储过程

    使用EF Core框架能快速的帮助我们进行常规的数据处理和项目开发,但是ORM虽然好用,但是在许多复杂逻辑的数据处理时,我个人还是偏向用SQL和存储过程的方式去处理,但是研究了一下目前最新版本的EF ...

  3. mysql 导入csv文件

    导入时,系统会默认一个导入路径,如果导入路径不是默认路径,会报 The MySQL server is running with the --secure-file-priv option so it ...

  4. 全面认识一下.NET 4.0的缓存功能 (转)

    转自:http://www.cnblogs.com/hjf1223/archive/2010/07/16/net_4_caching.html 很多关于.NET 4.0新特性的介绍,缓存功能的增强肯定 ...

  5. CentOS7 配置静态 ip

    1. 为 CentOS7 配置静态 ip 1.1 修改文件/etc/sysconfig/network-scripts/ifcfg-ens33 sudo vi /etc/sysconfig/netwo ...

  6. TruncateATable 清除一张表

    当我们想删除一张表的全部数据时,我们可以使用 truncate 关键字,但如果要删除的表的主键被引用了,那么就无法执行语句. 1.制作清除数据的工具 ,在 nuget 控制台中输入 Install-P ...

  7. windows Server 2012/2016 路由和远程访问,PPPOE,ADSL,连接接口时出现一个错误,连接被远程计算机终止

    经过查询资料,是由mprddm.dll的bug引起的. 修改位置: 将je修改为jmp. 查找修改位置,可参考 前面的RasGetPortUserData的调用,或者 后面的 字符串 64位dll可使 ...

  8. SDN 第五次上机作业

    1.搭建如下拓扑并连接控制器 2.下发相关流表和组表实现负载均衡 s1: s2: s3: s4: 3.抓包分析验证负载均衡 s4-eth1: s4-eth2: s4-eth3

  9. 未能找到 CodeDom 提供程序类型“Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider,

    未能找到 CodeDom 提供程序类型“Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft ...

  10. 很不错的关于依赖注入和AOP的系列文章

    http://blog.csdn.net/tittop/article/details/6716033