【递归】【线段树】【堆】AtCoder Regular Contest 080 E - Young Maids
给你一个1~n的排列p,n是偶数,每次从中任选一对相邻的数出来,插到排列q的开头,如此循环,问你所能得到的字典序最小的排列q。

我们先确定q开头的两个数q1,q2,q1一定是p的奇数位的最小的数,而q2一定是q1后面最小的偶数位的数,这很显然。
然后记q1,q2在p中的位置分别是L,R,把p分成三段[1,L],[L+1,R-1],[R+1,n],递归处理,当前区间[l,r],每次取的一对的左端点L必然是与当前区间左端点l奇偶性相同的最小的数,而R必然是L右侧与当前区间左端点l奇偶性不同的最小的数。
可以对奇数位和偶数位分别维护一个线段树。
重点是输出答案,我们从前往后构造q,我们发现,所有的数对形成了一个树形结构,比如说[l,r],通过之前我们说的过程,取得数对L,R,则[L,R]之间的数对都必须在L,R输出之后才能输出,我们把这些数对记作[L,R]的子树,递归把树建出来。
然后对我们构造出的这棵树,一开始把所有根的儿子加入堆,我们每次取当前堆里数对左侧的数最小的,输出,然后把它的儿子都加进堆,因为它的所有儿子都“解除了封锁”。如此直到堆空即可。
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
priority_queue<int,vector<int>,greater<int> >Heap;
#define lson rt<<1,l,m
#define rson rt<<1|1,m+1,r
int v[200005],first[200005],nex[200005],e;
void AddEdge(int U,int V){
v[++e]=V;
nex[e]=first[U];
first[U]=e;
}
int a[200005],cnt,ma[200005],pai[200005];
int minv[2][100005<<4],n,pos[200005];
void update(int o,int p,int v,int rt,int l,int r)
{
if(l==r)
{
minv[o][rt]+=v;
return;
}
int m=(l+r>>1);
if(p<=m) update(o,p,v,lson);
else update(o,p,v,rson);
minv[o][rt]=min(minv[o][rt<<1],minv[o][rt<<1|1]);
}
int query(int o,int ql,int qr,int rt,int l,int r)
{
if(ql<=l&&r<=qr) return minv[o][rt];
int m=(l+r>>1);
int res=2147483647;
if(ql<=m) res=min(res,query(o,ql,qr,lson));
if(m<qr) res=min(res,query(o,ql,qr,rson));
return res;
}
void work(int l,int r,int f){
if(l>=r){
return;
}
int L=pos[query(l&1,ma[l],(l%2 == r%2) ? ma[r] : ma[r-1],1,1,n/2)];
int R=pos[query((L+1)&1,ma[L+1],((L+1)%2 == r%2) ? ma[r] : ma[r-1],1,1,n/2)];
pai[a[L]]=a[R];
AddEdge(a[f],a[L]);
work(l,L-1,f);
work(L+1,R-1,L);
work(R+1,r,f);
}
int main(){
// freopen("c.in","r",stdin);
scanf("%d",&n);
for(int i=1;i<=n;++i){
scanf("%d",&a[i]);
pos[a[i]]=i;
update(i&1,i/2+(i&1),a[i],1,1,n/2);
ma[i]=i/2+(i&1);
}
if(n==2){
printf("%d %d\n",a[1],a[2]);
return 0;
}
work(1,n,0);
for(int i=first[0];i;i=nex[i]){
Heap.push(v[i]);
}
while(!Heap.empty()){
int U=Heap.top(); Heap.pop();
cnt+=2;
printf("%d %d%c",U,pai[U],cnt==n ? '\n' : ' ');
for(int i=first[U];i;i=nex[i]){
Heap.push(v[i]);
}
}
return 0;
}
【递归】【线段树】【堆】AtCoder Regular Contest 080 E - Young Maids的更多相关文章
- 【AtCoder Regular Contest 080E】Young Maids [堆][线段树]
Young Maids Time Limit: 50 Sec Memory Limit: 512 MB Description 给定一个排列,每次选出相邻的两个放在队头,要求字典序最小. Input ...
- AtCoder Regular Contest 080 (ARC080) E - Young Maids 线段树 堆
原文链接http://www.cnblogs.com/zhouzhendong/p/8934377.html 题目传送门 - ARC080 E - Young Maids 题意 给定一个长度为$n$的 ...
- AtCoder Regular Contest 080 E - Young Maids
地址:http://arc080.contest.atcoder.jp/tasks/arc080_c 题目: E - Young Maids Time limit : 2sec / Memory li ...
- AtCoder Regular Contest 080
手贱去开了abc,这么无聊.直接arc啊 C - 4-adjacent Time limit : 2sec / Memory limit : 256MB Score : 400 points Prob ...
- AtCoder Regular Contest 080 E:Young Maids
题目传送门:https://arc080.contest.atcoder.jp/tasks/arc080_c 题目翻译 给你一个\(n\)的排列\(p\),一个空序列\(q\),你每次可以从\(p\) ...
- AtCoder Regular Contest 080 D - Grid Coloring
地址:http://arc080.contest.atcoder.jp/tasks/arc080_b 题目: D - Grid Coloring Time limit : 2sec / Memory ...
- AtCoder Regular Contest 080 C - 4-adjacent
地址:http://arc080.contest.atcoder.jp/tasks/arc080_a 题目: C - 4-adjacent Time limit : 2sec / Memory lim ...
- AtCoder Regular Contest 080 [CDEF]
C - 4-adjacent Time limit : 2sec / Memory limit : 256MB Problem Statement We have a sequence of leng ...
- 【Atcoder】ARC 080 E - Young Maids
[算法]数学+堆 [题意]给定n个数的排列,每次操作可以取两个数按序排在新序列的头部,求最小字典序. [题解] 转化为每次找字典序最小的两个数按序排在尾部,则p1和p2的每次选择都必须满足:p1在当前 ...
随机推荐
- vue-awesome-swipe 基于vue使用的轮播组件 使用(改)
npm install vue-awesome-swiper --save //基于vue使用的轮播组件 <template> <swiper :options="swi ...
- python初步学习-pycharm使用 (二)
pycharm调试模式 假设我们的程序在运行过程中命中了一个错误,那我们如何定位错误发生的位置?这就需要进行调试. 在Pycharm中我们可以在其中直接对程序进行调试,唯一需要做的准备工作就是在程序必 ...
- webpack_配置和使用教程
webpack是一个模块打包的工具,它的作用是把互相依赖的模块处理成静态资源. webpack 可以使用 loader 来预处理文件.这允许你打包除 JavaScript 之外的任何静态资源.你可以使 ...
- Tornado 安装及简单程序示例
1.安装步骤:tar xvzf tornado-3.2.tar.gz cd tornado-3.2 python setup.py build sudo python setup.py install ...
- 为什么IO多路复用需要采用非阻塞式IO
近段时间开始学习<Unix网络编程>,代码实现了一个简单的IO多路复用+阻塞式的服务端,在学习了非阻塞式IO后,有一个疑问,即: 假如调用了select,并且关注了几个描述字,当关注的描述 ...
- Linux线程同步
1. 线程同步: 当多个控制线程共享相同的内存时,需要确保每个线程看到一致的数据视图.当某个线程可以修改变量,而其他线程也可以读取或者修改这个变量的时候,就需要对这些线程进行同步,以确保他们在访问变量 ...
- qgis 插件开发
qgis 插件开发 http://blog.csdn.net/v6543210/article/details/40480341
- python近期遇到的一些面试问题(一)
整理一下最近被问到的一些高频率的面试问题.总结一下方便日后复习巩固用,同时希望可以帮助一些朋友们. 1.python的基本数据类型 主要核心类型分为两类不可变类型:数字(int float bool ...
- 谈谈mybatis逆向工程中的Example类
参考博客: http://openwares.net/database/mybatis_generator_example.html 一.Example类的作用:一个用于筛选复杂条件的类 二.Exam ...
- web中的CSS、Xpath等路径定位方法学习
今天不到八点就到公司了,来的比较早,趁着有点时间,总结下web中的CSS.Xpath等路径定位定位的方式吧! 简单的介绍下xpath和css的定位 理论知识就不罗列了 还是利用博客园的首页.直接附上代 ...