Young Maids

Time Limit: 50 Sec  Memory Limit: 512 MB

Description

  给定一个排列,每次选出相邻的两个放在队头,要求字典序最小。

Input

  第一行一个整数n,第二行n个数表示这个排列。

Output

  n个数表示答案。

Sample Input

  8
  4 6 3 2 8 5 7 1

Sample Output

  3 1 2 7 4 6 8 5

HINT

  n%2=0,2 <= n <= 2e5

Solution

  倒着考虑。
  我们维护一个小根堆,堆里面存[l, r, val],表示在区间[l, r]中选择两个元素,第一个元素A的权值为val(保证合法),以val为第一关键字

  那么显然,我们每次选出堆顶进行操作

  显然,若我们取走了A,B(pos[A] < pos[B])[l,r]就被拆成了 [l,A-1], [A+1,B-1], [B+1,r],我们要保证每一个区间长度都是偶数
  那么只要有,pos[A]%2 == pos[l]%2,pos[B]%2 == pos[r]%2
  又由于我们每次减少两个数,所以这样显然可以保证 pos[B]-pos[A]+1 % 2 == 0

  现在问题就是怎么求出A、B具体是那两个数,显然写个线段树维护一下 某段区间内奇数/偶数位置的min_val和所在的pos即可。

Code

  1. #include<iostream>
  2. #include<string>
  3. #include<algorithm>
  4. #include<cstdio>
  5. #include<cstring>
  6. #include<cstdlib>
  7. #include<cmath>
  8. #include<queue>
  9. using namespace std;
  10. typedef long long s64;
  11.  
  12. const int ONE = ;
  13. const int INF = ;
  14.  
  15. int get()
  16. {
  17. int res = , Q = ; char c;
  18. while( (c = getchar()) < || c > )
  19. if(c == '-') Q = -;
  20. if(Q) res = c - ;
  21. while( (c = getchar()) >= && c <= )
  22. res = res * + c - ;
  23. return res * Q;
  24. }
  25.  
  26. int n;
  27. int a[ONE];
  28.  
  29. struct point
  30. {
  31. int id, val;
  32. friend bool operator <(point a, point b)
  33. {
  34. if(a.val != b.val) return a.val < b.val;
  35. return a.id < b.id;
  36. }
  37. };
  38. point res;
  39.  
  40. namespace Seg
  41. {
  42. struct power {point odd, eve;} Node[ONE * ];
  43.  
  44. void Build(int i, int l, int r)
  45. {
  46. Node[i].odd.val = Node[i].eve.val = INF;
  47. if(l == r)
  48. {
  49. if(l & ) Node[i].odd = (point){l, a[l]};
  50. else Node[i].eve = (point){l, a[l]};
  51. return;
  52. }
  53. int mid = l + r >> ;
  54. Build(i << , l, mid), Build(i << | , mid + , r);
  55. Node[i].odd = min(Node[i << ].odd, Node[i << | ].odd);
  56. Node[i].eve = min(Node[i << ].eve, Node[i << | ].eve);
  57. }
  58.  
  59. void Query(int i, int l, int r, int L, int R, int opt)
  60. {
  61. if(L <= l && r <= R)
  62. {
  63. if(opt == ) res = min(res, Node[i].odd);
  64. else res = min (res, Node[i].eve);
  65. return;
  66. }
  67. int mid = l + r >> ;
  68. if(L <= mid) Query(i << , l, mid, L, R, opt);
  69. if(mid + <= R) Query(i << | , mid + , r, L, R, opt);
  70. }
  71. }
  72.  
  73. struct power
  74. {
  75. int l, r, val;
  76. bool operator <(power a) const
  77. {
  78. if(a.val != val) return a.val < val;
  79. return a.l < l;
  80. }
  81. };
  82. priority_queue <power> q;
  83.  
  84. point Get(int l, int r, int opt)
  85. {
  86. res = (point){n + , INF};
  87. Seg::Query(, , n, l, r, opt);
  88. return res;
  89. }
  90.  
  91. void Add(int l, int r)
  92. {
  93. if(l > r) return;
  94. q.push((power){l, r, Get(l, r, l % ).val});
  95. }
  96.  
  97. int main()
  98. {
  99. n = get();
  100. for(int i = ; i <= n; i++)
  101. a[i] = get();
  102.  
  103. Seg::Build(, , n);
  104. Add(, n);
  105.  
  106. for(int i = ; i <= n / ; i++)
  107. {
  108. power u = q.top(); q.pop();
  109. point A = Get(u.l, u.r - , u.l % );
  110. point B = Get(A.id + , u.r, u.r % );
  111. printf("%d %d ", A.val, B.val);
  112.  
  113. Add(u.l, A.id - ), Add(A.id + , B.id - ), Add(B.id + , u.r);
  114. }
  115. }

【AtCoder Regular Contest 080E】Young Maids [堆][线段树]的更多相关文章

  1. Atcoder Grand Contest 023 E - Inversions(线段树+扫描线)

    洛谷题面传送门 & Atcoder 题面传送门 毒瘤 jxd 作业-- 首先我们不能直接对所有排列计算贡献对吧,这样复杂度肯定吃不消,因此我们考虑对每两个位置 \(x,y(x<y)\), ...

  2. 【AtCoder Grand Contest 001F】Wide Swap [线段树][拓扑]

    Wide Swap Time Limit: 50 Sec  Memory Limit: 512 MB Description Input Output Sample Input 8 3 4 5 7 8 ...

  3. AtCoder Regular Contest 088 E - Papple Sort(树状数组+结论)

    结论:每次把字符丢到最外面最优,用树状数组统计答案,把字符放到最外边后可以当成消失了,直接在树状数组上删掉就好. 感性理解是把字符丢到中间会增加其他字符的移动次数,但是丢到外面不会,所以是正确的. # ...

  4. AtCoder Regular Contest 069 F Flags 二分,2-sat,线段树优化建图

    AtCoder Regular Contest 069 F Flags 二分,2-sat,线段树优化建图 链接 AtCoder 大意 在数轴上放上n个点,点i可能的位置有\(x_i\)或者\(y_i\ ...

  5. AtCoder Regular Contest 061

    AtCoder Regular Contest 061 C.Many Formulas 题意 给长度不超过\(10\)且由\(0\)到\(9\)数字组成的串S. 可以在两数字间放\(+\)号. 求所有 ...

  6. AtCoder Regular Contest 094 (ARC094) CDE题解

    原文链接http://www.cnblogs.com/zhouzhendong/p/8735114.html $AtCoder\ Regular\ Contest\ 094(ARC094)\ CDE$ ...

  7. AtCoder Regular Contest 092

    AtCoder Regular Contest 092 C - 2D Plane 2N Points 题意: 二维平面上给了\(2N\)个点,其中\(N\)个是\(A\)类点,\(N\)个是\(B\) ...

  8. AtCoder Regular Contest 093

    AtCoder Regular Contest 093 C - Traveling Plan 题意: 给定n个点,求出删去i号点时,按顺序从起点到一号点走到n号点最后回到起点所走的路程是多少. \(n ...

  9. AtCoder Regular Contest 094

    AtCoder Regular Contest 094 C - Same Integers 题意: 给定\(a,b,c\)三个数,可以进行两个操作:1.把一个数+2:2.把任意两个数+1.求最少需要几 ...

随机推荐

  1. vue-cli 安装步骤(转载)

    参考资料:Vue2.0 新手完全填坑攻略—从环境搭建到发布 1.Node.js安装 https://nodejs.org/en/download/ 2.安装vue-cli npm install -g ...

  2. 转载---Atom编辑器常用快捷键

    常用快捷键–亲测及翻译 英文 中文 快捷键 功能 New Window 新建界面窗口 Ctrl + Shift + N 如中文意思 New File 新建文件 Ctrl + N 如中文意思 Open ...

  3. Scrum 项目7.0——第一个Sprint的总结和读后感

          总结: 通过这一次的Sprint,我了解了Sprint的整个流程,也学会了编制backlog,也了解了在软件工程中,一个团队的任务是怎么样分配和一个项目是怎么样开展的.从对软件工程的认识只 ...

  4. LeetCode题解:(114) Flatten Binary Tree to Linked List

    题目说明 Given a binary tree, flatten it to a linked list in-place. For example, Given 1 / \ 2 5 / \ \ 3 ...

  5. apache DBUtils 使用例子demo

    转自:http://blog.csdn.net/earbao/article/details/44901061 apache DBUtils是java编程中的数据库操作实用工具,小巧简单实用, 1.对 ...

  6. VMIC

    1. wmic 的简介 wmic -? [全局开关] <命令> 可以使用以下全局开关: /NAMESPACE 别名在其上操作的命名空间的路径. /ROLE 包含别名定义的角色的路径. /N ...

  7. 创建一个背景透明的UIViewController

    有时候想让UIViewController背景透明,让我们可以看到下层的UI,直接设置它的背景颜色为clearColor(),还是有黑色的默认背景在那里.下面是解决该问题的例子: 在storyboar ...

  8. BZOJ2789 [Poi2012]Letters 【树状数组】

    题目链接 BZOJ 题解 如果我们给\(A\)中所有字母按顺序编号,给\(B\)中所有字母编上相同的号码 对于\(B\)中同一种,显然号码应该升序 然后求逆序对即可 #include<algor ...

  9. VS2010 重命名文件:源文件名和目标文件名相同 的解决方案

    想要在“”解决方案资源管理器“”中修改一个已经写好的文件的文件名,如图: 在改了几次后就出现了如图的问题: 然而在“解决方案资源管理器”中并没有看到,于是我打开了工程在磁盘中的位置文件夹: 意外发现了 ...

  10. python的字符串截取

    str = ‘’ :] #截取第一位到第三位的字符 print str[:] #截取字符串的全部字符 :] #截取第七个字符到结尾 ] #截取从头开始到倒数第三个字符之前 ] #截取第三个字符 ] # ...