给你一个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的更多相关文章

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

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

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

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

  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. AtCoder Regular Contest 080

    手贱去开了abc,这么无聊.直接arc啊 C - 4-adjacent Time limit : 2sec / Memory limit : 256MB Score : 400 points Prob ...

  5. AtCoder Regular Contest 080 E:Young Maids

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

  6. AtCoder Regular Contest 080 D - Grid Coloring

    地址:http://arc080.contest.atcoder.jp/tasks/arc080_b 题目: D - Grid Coloring Time limit : 2sec / Memory ...

  7. AtCoder Regular Contest 080 C - 4-adjacent

    地址:http://arc080.contest.atcoder.jp/tasks/arc080_a 题目: C - 4-adjacent Time limit : 2sec / Memory lim ...

  8. AtCoder Regular Contest 080 [CDEF]

    C - 4-adjacent Time limit : 2sec / Memory limit : 256MB Problem Statement We have a sequence of leng ...

  9. 【Atcoder】ARC 080 E - Young Maids

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

随机推荐

  1. Codeforces Round #483 (Div. 2) [Thanks, Botan Investments and Victor Shaburov!]

    题目链接:http://codeforces.com/contest/984 A. Game time limit per test:2 seconds memory limit per test:5 ...

  2. patch需要数据格式前端算法,patch算法基础,两个对象对比取差异属性

    在我们的前端开发过程中,表单是最常见不过的了,一般我们创建表单的时候习惯使用post方法来提交数据,编辑表单时候喜欢put,但是当表单的数据非常多的时候,编辑起来很麻烦,首先需要获取初始化数据,然后把 ...

  3. Ribbon/Feign/Zuul retry

    原文 https://github.com/spring-cloud/spring-cloud-netflix/issues/1577 I'm using Spring Cloud Camden SR ...

  4. vue.js将一个对象的所有属性作为prop进行传递

    1.方法一:使用不带参数的v-bind写法 <div id="app"> <child v-bind="todo"></child ...

  5. 集合框架源码学习之ArrayList

    目录: 0-0-1. 前言 0-0-2. 集合框架知识回顾 0-0-3. ArrayList简介 0-0-4. ArrayList核心源码 0-0-5. ArrayList源码剖析 0-0-6. Ar ...

  6. html meta标签作用

    1.概要 标签提供关于HTML文档的元数据.元数据不会显示在页面上,但是对于机器是可读的.它可用于浏览器(如何显示内容或重新加载页面),搜索引擎(关键词),或其他web服务. 必要属性: conten ...

  7. 【DataScience学习笔记】Coursera课程《数据科学家的工具箱》 约翰霍普金斯大学——Week3 Conceptual Issues课堂笔记

    Coursera课程<数据科学家的工具箱> 约翰霍普金斯大学 Week3 Conceptual Issues Types of Questions Types of Data Scienc ...

  8. 宿主机mount虚拟机镜像文件

    转载 mount挂载虚拟机镜像文件 使用mount挂载ubuntu虚拟机所在的img文件的时候,执行: “sudo mount -o loop xxx.img /mnt/xxx”, 系统提示: “mo ...

  9. dump_stack 实现分析【转】

    转自:http://kernel.meizu.com/2017/03/18-40-19-dump_stack.html 1 简介 说起 dump_stack() ,相信从事 Linux 内核或者驱动相 ...

  10. perl 函数参数传递与返回值(一)

    perl 函数参数传递与返回值(一) http://www.cnblogs.com/tobecrazy/archive/2013/06/11/3131887.html