BZOJ原题链接

洛谷原题链接

第一个问题是经典的最多不相交区间问题,用贪心即可解决。

主要问题是第二个,求最小字典序的方案。

我们可以尝试从\(1\to n\)扫一遍所有区间,按顺序对每一个不会使答案变差的区间都尝试着去填,这样就可以保证方案的字典序最小。

考虑如果快速判断该区间是否能成为最优解,开头先按右端点从小到大排序,左端点从大到小排序,再去除有包含关系的区间,这样使得讨论更为简单。

设待插入的区间为\([r,l]\),该区间左边的第一个已插入的区间的右端点为\(L\),右边的第一个已插入的区间的左端点为\(R\),\(S[i][j]\)表示\([i,j]\)间有多少已插入的区间。

则该区间能插入必须满足\(S[L + 1][R - 1] = S[L + 1][r - 1] + S[l + 1][R - 1] + 1\)。

对于快速计算\(S\),我们可以采用倍增的思想,设\(ne[x][i]\)表示第\(x\)个区间后选择\(2^i\)个区间的最后一个区间下标,可以使用倍增在\(nlogn\)内预处理出来。

维护已插入区间可以使用\(C++\ STL\ set\)。

  1. #include<cstdio>
  2. #include<algorithm>
  3. #include<cmath>
  4. #include<set>
  5. using namespace std;
  6. const int N = 2e5 + 10;
  7. const int M = 18;
  8. struct dd{
  9. int x, y;
  10. bool operator < (const dd &b) const
  11. {
  12. if (!(y ^ b.y))
  13. return x > b.x;
  14. return y < b.y;
  15. }
  16. };
  17. dd a[N], b[N];
  18. int X[N], Y[N], ne[N][M], m, gn;
  19. set<dd>S;
  20. inline int re()
  21. {
  22. int x = 0;
  23. char c = getchar();
  24. bool p = 0;
  25. for (; c < '0' || c > '9'; c = getchar())
  26. p |= c == '-';
  27. for (; c >= '0' && c <= '9'; c = getchar())
  28. x = x * 10 + c - '0';
  29. return p ? -x : x;
  30. }
  31. inline int lowbod(int x)
  32. {
  33. int l = 1, r = m, mid, an = m + 1;
  34. while (l <= r)
  35. {
  36. mid = (l + r) >> 1;
  37. if (X[mid] >= x)
  38. {
  39. an = mid;
  40. r = mid - 1;
  41. }
  42. else
  43. l = mid + 1;
  44. }
  45. return an;
  46. }
  47. inline int calc(int l, int r)
  48. {
  49. int x = lowbod(l);
  50. if (x > m || Y[x] > r)
  51. return 0;
  52. int s = 1;
  53. for (int i = gn; ~i; i--)
  54. if (ne[x][i] && Y[ne[x][i]] <= r)
  55. {
  56. s += 1 << i;
  57. x = ne[x][i];
  58. }
  59. return s;
  60. }
  61. int main()
  62. {
  63. int i, j, n, l, r, L, R;
  64. n = re();
  65. for (i = 1; i <= n; i++)
  66. {
  67. a[i].x = re();
  68. a[i].y = re();
  69. b[i] = a[i];
  70. }
  71. sort(b + 1, b + n + 1);
  72. for (i = 1; i <= n; i++)
  73. if (b[i].x > b[m].x || !m)
  74. b[++m] = b[i];
  75. for (i = 1; i <= m; i++)
  76. {
  77. X[i] = b[i].x;
  78. Y[i] = b[i].y;
  79. }
  80. for (i = j = 1; i <= m; i++)
  81. {
  82. for (; j <= m && b[j].x <= b[i].y; j++);
  83. if (j <= m)
  84. ne[i][0] = j;
  85. }
  86. gn = log2(m);
  87. for (j = 1; j <= gn; j++)
  88. for (i = 1; i <= m; i++)
  89. ne[i][j] = ne[ne[i][j - 1]][j - 1];
  90. printf("%d\n", calc(-2e9, 2e9));
  91. S.insert((dd){-2e9, -2e9});
  92. S.insert((dd){2e9, 2e9});
  93. for (i = 1; i <= n; i++)
  94. {
  95. set<dd>::iterator x = S.lower_bound(a[i]), y;
  96. --(y = x);
  97. L = y -> y;
  98. r = a[i].x;
  99. l = a[i].y;
  100. R = x -> x;
  101. if (L >= r || l >= R)
  102. continue;
  103. if (!(calc(L + 1, R - 1) ^ (calc(L + 1, r - 1) + calc(l + 1, R - 1) + 1)))
  104. {
  105. printf("%d ", i);
  106. S.insert(a[i]);
  107. }
  108. }
  109. return 0;
  110. }

BZOJ1178或洛谷3626 [APIO2009]会议中心的更多相关文章

  1. Luogu 3626 [APIO2009]会议中心

    很优美的解法. 推荐大佬博客 如果没有保证字典序最小这一个要求,这题就是一个水题了,但是要保证字典序最小,然后我就不会了…… 如果一条线段能放入一个区间$[l', r']$并且不影响最优答案,那么对于 ...

  2. [APIO2009]会议中心(贪心)

    P3626 [APIO2009]会议中心 题目描述 Siruseri 政府建造了一座新的会议中心.许多公司对租借会议中心的会堂很 感兴趣,他们希望能够在里面举行会议. 对于一个客户而言,仅当在开会时能 ...

  3. [APIO2009]会议中心

    [APIO2009]会议中心 题目大意: 原网址与样例戳我! 给定n个区间,询问以下问题: 1.最多能够选择多少个不相交的区间? 2.在第一问的基础上,输出字典序最小的方案. 数据范围:\(n \le ...

  4. 【题解】[APIO2009]会议中心

    [题解][P3626 APIO2009]会议中心 真的是一道好题!!!刷新了我对倍增浅显的认识. 此题若没有第二份输出一个字典序的方案,就是一道\(sort+\)贪心,但是第二问使得我们要用另外的办法 ...

  5. BZOJ.1178.[APIO2009]会议中心(贪心 倍增)

    BZOJ 洛谷 \(Description\) 给定\(n\)个区间\([L_i,R_i]\),要选出尽量多的区间,并满足它们互不相交.求最多能选出多少个的区间以及字典序最小的方案. \(n\leq2 ...

  6. BZOJ1179或洛谷3672 [APIO2009]抢掠计划

    BZOJ原题链接 洛谷原题链接 在一个强连通分量里的\(ATM\)机显然都可被抢,所以先用\(tarjan\)找强连通分量并缩点,在缩点的后的\(DAG\)上跑最长路,然后扫一遍酒吧记录答案即可. # ...

  7. 【题解】洛谷P3627 [APIO2009]抢掠计划(缩点+SPFA)

    洛谷P3627:https://www.luogu.org/problemnew/show/P3627 思路 由于有强连通分量 所以我们可以想到先把整个图缩点 缩点完之后再建一次图 把点权改为边权 并 ...

  8. BZOJ1178 APIO2009 会议中心 贪心、倍增

    传送门 只有第一问就比较水了 每一次贪心地选择当前可以选择的所有线段中右端点最短的,排序之后扫一遍即可. 考虑第二问.按照编号从小到大考虑每一条线段是否能够被加入.假设当前选了一个区间集合\(T\), ...

  9. 洛谷P3625 - [APIO2009]采油区域

    Portal Description 给出一个\(n\times m(n,m\leq1500)\)的矩阵,从中选出\(3\)个互不相交的\(k\times k\)方阵,使得被选出的数的和最大. Sol ...

随机推荐

  1. OCR技术浅探(转)

    网址:https://spaces.ac.cn/archives/3785 OCR技术浅探 作为OCR系统的第一步,特征提取是希望找出图像中候选的文字区域特征,以便我们在第二步进行文字定位和第三步进行 ...

  2. shell 脚本传参

    在 shell 中我们会见到  $0.$1.$2这样的符号,这是什么意思呢? 简单来说 $0 就是你写的shell脚本本身的名字,$1 是你给你写的shell脚本传的第一个参数,$2 是你给你写的sh ...

  3. Redis服务器开启远程访问

    重启  ps aux|grep redis root 32684 0.0 0.0 48452 6944 ? Ssl 21:27 0:00 ./redis-server *:6379 kill了这个进程 ...

  4. 面试真题-----hashMap原理

    HashMap详解   JDK1.8对HashMap底层的实现进行了优化,例如引入红黑树的数据结构和扩容的优化等 简介 Java为数据结构中的映射定义了一个接口java.util.Map HashMa ...

  5. jdbc连接mysql/oracle数据库

    driver-class-name : com.mysql.jdbc.Driver url : jdbc:mysql://localhost:3306/数据库名 username:   root pa ...

  6. Oracle常用查看表结构命令(转)

    转自:http://www.cnblogs.com/qingsong-do/archive/2011/11/29/2267244.html 获取表: select table_name from us ...

  7. elasticsearch ik安装

    /usr/share/elasticsearch/bin/elasticsearch-plugin install https://github.com/medcl/elasticsearch-ana ...

  8. verilog之inout

    1.inout 类型的data信号 写操作有效时(rd_wr_l=0):data端口输入信号,此时data为高阻态,允许对其进行赋值. 读操作有效时(rd_wr_l=1):data端口输出信号,此时d ...

  9. Flask中的蓝图(BluePrint)、

    蓝图 1.初识Flask蓝图(BluePrint) 创建一个项目然后将目录结构做成: user.py中的内容 from flask import Blueprint, render_template ...

  10. PL/SQL Dev连接Oracle弹出空白提示框的解决方法分享

    第一次安装Oracle,装在虚拟机中,用PL/SQL Dev连接远程数据库的时候老是弹出空白提示框,网上找了很久,解决方法也很多,可是就是没法解决我这种情况的. 出现这种问题,解决方法大概有这几种: ...