一道挺有意思的题目,在这里记录一下。

题目大意

给你一个长度为 \(n\) 的排列,每一次你可以取出相邻的两个数将其放在答案序列的开头,最后问你字典序最小的答案序列是什么。

题解

由于最后是求字典序最小,所以我们肯定需要倒序求解,所以我们需要考虑如何取才能使得剩下的序列合法。

如果我们在区间 \([L,R]\) 当前选择点 \(l\) 和点 \(r\) ,那么最后的区间很显然会被我们分成三部分, \([L,l-1]\) , \([l+1,r-1]\) 和 \([r+1,R]\) 。而且这三个区间的长度必须为偶数才可以满足区间同时也可分。我们就可以用一个优先队列来模拟一下,每一次取出当前所以区间中可以选择字典最小的点对的区间,再将其拆分为三个区间。不断重复此操作直到最后所有的数都被取出即可。

代码

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. const int N=2e5+5;
  4. int n,a[N],b[N];
  5. struct Point{int data,loc;};
  6. bool operator < (const Point a,const Point b){return a.data<b.data;}
  7. struct Seg_Tree
  8. {
  9. struct Node{Point data;}tr[N<<2];
  10. void up(int u){tr[u].data=min(tr[u<<1].data,tr[u<<1|1].data);}
  11. void build(int u,int l,int r,int a[])
  12. {
  13. if(l==r)
  14. {
  15. tr[u].data.data=a[l];
  16. tr[u].data.loc=l;
  17. return ;
  18. }
  19. int mid=(l+r)>>1;
  20. build(u<<1,l,mid,a);
  21. build(u<<1|1,mid+1,r,a);
  22. up(u);
  23. }
  24. void chg(int u,int l,int r,int x)
  25. {
  26. if(l==r){tr[u].data.data=1e9+7;return ;}
  27. int mid=(l+r)>>1;
  28. if(x<=mid) chg(u<<1,l,mid,x);
  29. else chg(u<<1|1,mid+1,r,x);
  30. up(u);
  31. }
  32. Point query(int u,int l,int r,int x,int y)
  33. {
  34. if(x<=l&&r<=y) return tr[u].data;
  35. int mid=(l+r)>>1;Point res={1000000007,0};
  36. if(x<=mid) res=min(res,query(u<<1,l,mid,x,y));
  37. if(y>mid) res=min(res,query(u<<1|1,mid+1,r,x,y));
  38. return res;
  39. }
  40. }t[2];//0为偶,1为奇
  41. struct Data{int l,r;Point data;};
  42. bool operator < (const Data a,const Data b){return a.data.data>b.data.data;}
  43. priority_queue<Data> q;
  44. vector<int> res;
  45. int main()
  46. {
  47. cin>>n;
  48. for(int i=1,x;i<=n;++i)
  49. {
  50. scanf("%d",&x);
  51. if(i&1) a[i]=1e9+7,b[i]=x;
  52. else a[i]=x,b[i]=1e9+7;
  53. }
  54. t[0].build(1,1,n,a);
  55. t[1].build(1,1,n,b);
  56. Data tmp;
  57. tmp.l=1,tmp.r=n;
  58. tmp.data=t[1].query(1,1,n,1,n);
  59. q.push(tmp);
  60. for(int i=1;i<=n/2;++i)
  61. {
  62. tmp=q.top(),q.pop();
  63. int tag=tmp.l%2;
  64. // printf("%d\n",tag);
  65. Point L=tmp.data,R=t[tag^1].query(1,1,n,L.loc+1,tmp.r);
  66. // printf("%d %d %d %d\n",tmp.l,tmp.r,L.data,R.data);
  67. res.push_back(L.data),res.push_back(R.data);
  68. Data now;
  69. now.l=tmp.l,now.r=L.loc-1;
  70. if(now.l<=now.r)
  71. {
  72. now.data=t[tag].query(1,1,n,now.l,now.r);
  73. q.push(now);
  74. }
  75. now.l=L.loc+1,now.r=R.loc-1;
  76. if(now.l<=now.r)
  77. {
  78. now.data=t[tag^1].query(1,1,n,now.l,now.r);
  79. q.push(now);
  80. }
  81. now.l=R.loc+1,now.r=tmp.r;
  82. if(now.l<=now.r)
  83. {
  84. now.data=t[tag].query(1,1,n,now.l,now.r);
  85. q.push(now);
  86. }
  87. }
  88. for(int i=0;i<(int)res.size();++i) printf("%d ",res[i]);
  89. printf("\n");
  90. return 0;
  91. }

AT2688 [ARC080C] Young Maids的更多相关文章

  1. AtCoder Regular Contest 080 (ARC080) E - Young Maids 线段树 堆

    原文链接http://www.cnblogs.com/zhouzhendong/p/8934377.html 题目传送门 - ARC080 E - Young Maids 题意 给定一个长度为$n$的 ...

  2. 【AtCoder Regular Contest 080E】Young Maids [堆][线段树]

    Young Maids Time Limit: 50 Sec  Memory Limit: 512 MB Description 给定一个排列,每次选出相邻的两个放在队头,要求字典序最小. Input ...

  3. AtCoder Regular Contest 080 E - Young Maids

    地址:http://arc080.contest.atcoder.jp/tasks/arc080_c 题目: E - Young Maids Time limit : 2sec / Memory li ...

  4. Young Maids

    E - Young Maids Time limit : 2sec / Memory limit : 256MB Score : 800 points Problem Statement Let N  ...

  5. Atcoder arc080E Young Maids(线段树+优先队列)

    给出一个n排列,每次可以选择相邻的两个数字放在新的排列首部,问最后形成的新的排列字典序最小是? 考虑新排列的第一个数字,则应是下标为奇数的最小数,下标不妨设为i.第二个数字应该下标大于i且为偶数的最小 ...

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

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

  7. 【Atcoder】ARC 080 E - Young Maids

    [算法]数学+堆 [题意]给定n个数的排列,每次操作可以取两个数按序排在新序列的头部,求最小字典序. [题解] 转化为每次找字典序最小的两个数按序排在尾部,则p1和p2的每次选择都必须满足:p1在当前 ...

  8. AtCoder Regular Contest 080 E:Young Maids

    题目传送门:https://arc080.contest.atcoder.jp/tasks/arc080_c 题目翻译 给你一个\(n\)的排列\(p\),一个空序列\(q\),你每次可以从\(p\) ...

  9. Atcoder 乱做

    最近感觉自己思维僵化,啥都不会做了-- ARC103 F Distance Sums 题意 给定第 \(i\) 个点到所有点的距离和 \(D_i\) ,要求构造一棵合法的树.满足第 \(i\) 个点到 ...

随机推荐

  1. 转 Cache一致性和内存模型

    卢本伟牛逼,写得很好 https://wudaijun.com/2019/04/cpu-cache-and-memory-model/ 本文主要谈谈CPU Cache的设计,内存屏障的原理和用法,最后 ...

  2. cephonebox发布

    前言 现在已经是2016年收官的一个月了,之前一直想做一个calamari的集成版本,之所以有这个想法,是因为,即使在已经打好包的情况下,因为各种软件版本的原因,造成很多人无法配置成功,calamar ...

  3. Spring Boot优雅地处理404异常

    背景 在使用SpringBoot的过程中,你肯定遇到过404错误.比如下面的代码: @RestController @RequestMapping(value = "/hello" ...

  4. Python_pycharm调试模式+使用pycharm给python传递参数

    一.通过pycharm 给python传递函数 1. 在pycharm终端中写入要获取的参数,进行获取 1>启动pycharm 中Terminal(终端) 窗口 点击pycharm左下角的图标, ...

  5. 07 . 前端工程化(ES6模块化和webpack打包)

    模块化规范 传统开发模式主要问题 /* 1. 命名冲突 2. 文件依赖 */ 通过模块化解决上述问题 /* 模块化就是把单独的一个功能封装在一个模块(文件)中,模块之间相互隔离, 但是可以通过特定的接 ...

  6. Cisco思科模拟器路由器各个端口IP地址的配置及路由协议RIP的配置 入门详解 - 精简归纳

    Cisco思科模拟器路由器各个端口IP地址的配置及路由协议RIP的配置 入门详解 - 精简归纳 JERRY_Z. ~ 2020 / 11 / 21 转载请注明出处!️ 附: 交流方式: ️ ️ ️ Q ...

  7. To the Max(动态规划)

    Description Given a two-dimensional array of positive and negative integers, a sub-rectangle is any ...

  8. Shodan搜索引擎详解及Python命令行调用

    shodan常用信息搜索命令 shodan配置命令 shodan init T1N3uP0Lyeq5w0wxxxxxxxxxxxxxxx //API设置 shodan信息收集 shodan myip ...

  9. bWAPP----HTML Injection - Reflected (URL)

    HTML Injection - Reflected (URL) 核心代码 1 <div id="main"> 2 3 <h1>HTML Injection ...

  10. swupdate实例

    平台:imx8mm 系统:linux 4.4   如果需要系统了解swupdate,请参考文章:嵌入式系统更新swupdate分类   一.制作升级包 emmcsetup.lua用来描述update执 ...