1178: [Apio2009]CONVENTION会议中心

https://lydsy.com/JudgeOnline/problem.php?id=1178

分析:

  set+倍增。

  首先把所有有包含的去掉,只保留包含的最小的边(如果两条线段中的一条包含另一条,那么保留被包含的)然后此时就可以直接贪心了。直接从一条边找不想交的下一条边。然后就行了(因为此时没有包含的,左端点递增,右端点递增)。

  因为每条边的下一条是唯一的,那么可以倍增维护往后走2^i步,到的点。此时可以快速知道任意一段区间的最多可以有多少条边了。

  因为要字典序最小,从编号小的可以是枚举,如果这条边[l,r]可以加进去。tl,tr如下图所示。

  那么[l,r]可以加入的条件是,calc(tl+1,tr-1)=calc(tl+1,l-1)+calc(r+1,tr-1)+1,calc(l,r)表示l~r最多可以放几条线段。

代码:

  1. #include<cstdio>
  2. #include<algorithm>
  3. #include<cstring>
  4. #include<iostream>
  5. #include<cmath>
  6. #include<cctype>
  7. #include<set>
  8. #include<queue>
  9. #include<vector>
  10. #include<map>
  11. using namespace std;
  12. typedef long long LL;
  13.  
  14. inline int read() {
  15. int x=,f=;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-;
  16. for(;isdigit(ch);ch=getchar())x=x*+ch-'';return x*f;
  17. }
  18.  
  19. const int N = ;
  20. const int INF = 1e9;
  21. const int Log = ;
  22.  
  23. struct Edge{
  24. int l, r;
  25. Edge() { }
  26. Edge(int a,int b) { l = a, r = b; }
  27. bool operator < (const Edge &A) const {
  28. return r == A.r ? l > A.l : r < A.r;
  29. }
  30. }A[N], ori[N];
  31. int disc[N << ], f[N][Log + ], X[N], Y[N], m = ;
  32. set<Edge>s;
  33.  
  34. int Calc(int l,int r) {
  35. int p = lower_bound(X + , X + m + , l) - X, ans = ; // ans=1!!!
  36. if (Y[p] > r || p > m) return ;
  37. for (int i = Log; i >= ; --i)
  38. if (f[p][i] && Y[f[p][i]] <= r)
  39. ans += ( << i), p = f[p][i];
  40. return ans;
  41. }
  42.  
  43. int main() {
  44. int n = read();
  45. for (int i = ; i <= n; ++i) {
  46. A[i].l = read(), A[i].r = read();
  47. disc[i] = A[i].l, disc[i + n] = A[i].r;
  48. }
  49. sort(disc + , disc + n + n + );
  50. int cnt = ;
  51. for (int i = ; i <= n + n; ++i) if (disc[i] != disc[cnt]) disc[++cnt] = disc[i];
  52. for (int i = ; i <= n; ++i) {
  53. A[i].l = lower_bound(disc + , disc + cnt + , A[i].l) - disc;
  54. A[i].r = lower_bound(disc + , disc + cnt + , A[i].r) - disc;
  55. ori[i] = A[i];
  56. }
  57. sort(A + , A + n + );
  58. X[m] = A[m].l, Y[m] = A[m].r;
  59. for (int i = ; i <= n; ++i)
  60. if (A[i].l > A[m].l) A[++m] = A[i], X[m] = A[m].l, Y[m] = A[m].r;
  61. for (int i = , j = ; i <= m; ++i) {
  62. while (j <= m && A[j].l <= A[i].r) j ++;
  63. if (j <= m) f[i][] = j;
  64. }
  65. for (int j = ; j <= Log; ++j)
  66. for (int i = ; i <= m; ++i) f[i][j] = f[f[i][j - ]][j - ];
  67.  
  68. int ans = Calc(-INF, INF);
  69. cout << ans << "\n";
  70.  
  71. s.insert(Edge(INF, INF));
  72. s.insert(Edge(-INF, -INF));
  73.  
  74. int now = ;
  75. for (int i = ; i <= n; ++i) {
  76. set<Edge> :: iterator x = s.lower_bound(ori[i]), y = x; y --; // 端点没有重复的,可以直接set的lower_bound
  77. int tl = y->r, tr = x->l, l = ori[i].l, r = ori[i].r;
  78. if (tl >= l || tr <= r) continue;
  79. if (Calc(tl + , tr - ) == Calc(tl + , l - ) + Calc(r + , tr - ) + ) {
  80. if (++now == ans) return printf("%d",i), ;
  81. else printf("%d ",i);
  82. s.insert(ori[i]);
  83. }
  84. }
  85. return ;
  86. }

1178: [Apio2009]CONVENTION会议中心的更多相关文章

  1. bzoj 1178 [Apio2009]CONVENTION会议中心

    这题好难啊! 我好菜啊! 思路:对于最多线段不相交, 我们可以按左端点sort之后,贪心取. 但是这个题要求选取的线段排序之后序号的字典序最小. 那么我们如果按序号贪心地从大往小往里放, 那么对于第k ...

  2. bzoj 1178: [Apio2009]CONVENTION会议中心(少见做法掉落!)【贪心+二分】

    数组若干+手动二分一个的算法,bzoj rank8 ===============================废话分割线=================================== 我我 ...

  3. bzoj1178 [Apio2009]CONVENTION会议中心 区间dp+贪心

    [Apio2009]CONVENTION会议中心 Time Limit: 15 Sec  Memory Limit: 162 MBSubmit: 1130  Solved: 444[Submit][S ...

  4. BZOJ1178 [Apio2009]CONVENTION会议中心

    本文作者:ljh2000作者博客:http://www.cnblogs.com/ljh2000-jump/转载请注明出处,侵权必究,保留最终解释权! Description Siruseri政府建造了 ...

  5. 【bzoj1178】 Apio2009—CONVENTION会议中心

    http://www.lydsy.com/JudgeOnline/problem.php?id=1178 (题目链接) 题意 给出n个区间,问在区间两两不相交的情况下最多能选出多少区间,并输出字典序最 ...

  6. BZOJ1178 [Apio2009]CONVENTION会议中心 贪心 set

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1178 题意概括 一堆线段,现在取出最多条数,使其互不覆盖,并输出字典序最小的方案. 题解 这题好坑 ...

  7. 【BZOJ】【1178】【APIO2009】convention会议中心

    贪心 如果不考虑字典序的话,直接按右端点排序,能选就选,就可以算出ans…… 但是要算一个字典序最小的解就比较蛋疼了= = Orz了zyf的题解 就是按字典序从小到大依次枚举,在不改变答案的情况下,能 ...

  8. 【BZOJ-1178】CONVENTION会议中心 倍增 + set (神思路好题!)

    1178: [Apio2009]CONVENTION会议中心 Time Limit: 15 Sec  Memory Limit: 162 MBSubmit: 812  Solved: 323[Subm ...

  9. 【BZOJ 1178】【APIO 2009】CONVENTION会议中心

    http://www.lydsy.com/JudgeOnline/problem.php?id=1178 这道题想了好久没想明白,倍增数组通过看题解很快就明白了,但是一小段区间内应有的最多线段数一直不 ...

随机推荐

  1. 【vue】todolist小练习

    参考链接: http://www.imooc.com/learn/694 http://www.cnblogs.com/Chen-XiaoJun/p/6238137.html http://blog. ...

  2. indexzero/http-server-2-使用

    所以在ethereumjs-vm/examples/run-transactions-simple例子中要怎么使用http-server 1.首先在ethereumjs-vm/examples/run ...

  3. RSA加密算法和签名算法

    RSA加密算法 RSA公钥加密体制包含如下3个算法:KeyGen(密钥生成算法),Encrypt(加密算法)以及Decrypt(解密算法). .密钥生成算法以安全常数作为输入,输出一个公钥PK,和一个 ...

  4. ASP.Net GridView 基础 Template模板

    一.了解Template AlternatingItemTemplate定义交替行的内容和外观,如果没有规定模板,则使用ItemTemplate:EditItemTemplate定义当前正在编辑的行的 ...

  5. HDU 1007 Quoit Design(经典最近点对问题)

    传送门: http://acm.hdu.edu.cn/showproblem.php?pid=1007 Quoit Design Time Limit: 10000/5000 MS (Java/Oth ...

  6. Vcenter虚拟化三部曲----SQL Server 2008 R2 数据库安装

    操作系统    Windows server 2008 R2 数据库      SQL Server 2008 R2 注意:SQL Server 2008 R2需要操作系统首先安装.NET Frame ...

  7. Xcode缓存数据清除

    1. 移除 APP 打包的ipa历史版本(Archives) 不可恢复,就是你打的包,如果需要dysm文件,及时备份 路径:~/Library/Developer/Xcode/Archives 2. ...

  8. P1015 回文数解题思路(非原创)

    测试 #include<bits/stdc++.h> using namespace std; int n,m,step; string nn; int len,nex; bool dfs ...

  9. npm audit fix

    执行npm install 出现如下提醒   added 253 packages from 162 contributors and audited 1117 packages in 42.157s ...

  10. 用DBCC CHECK修复SQL2000的数据库一致性问题

    ) set @databasename='需要修复的数据库实体的名称' exec sp_dboption @databasename, N'single', N'true' --将目标数据库置为单用户 ...