题目传送门:https://arc080.contest.atcoder.jp/tasks/arc080_c

题目翻译

给你一个\(n\)的排列\(p\),一个空序列\(q\),你每次可以从\(p\)里选择相邻的两个元素按照原本的顺序放在\(q\)的首位。问可以得到的排列字典序最小是什么。长度小于等于\(2*10^5\)

题解

我们考虑倒着做。看看能最后一个被取出来的数最小是什么。显然,能在最后一对被取出来的数对第一个数在奇数位,第二个数在偶数位。

我们可以对奇数位的数字维护一个\(st\)表,偶数也维护一个。每次取出这一对数之后,就把当前区间分成了\([l,pos-1],[pos+1,tmp-1],[tmp+1,r]\)三段,其中中间一段数对的奇偶性要改变,然后递归去做就可以了。

最后拓扑加堆输出答案。

时间复杂度:\(O(nlogn)\)

空间复杂度:\(O(n)\)

代码如下:

#include <cmath>
#include <cstdio>
#include <algorithm>
using namespace std;
typedef pair<int,int> pii;
#define fr first
#define sc second const int maxn=2e5+5; pii node[maxn];
int n,rt,tot,cnt;
int f[20][maxn][2];
int a[maxn],now[maxn],pre[maxn],son[maxn]; int read() {
int x=0,f=1;char ch=getchar();
for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
return x*f;
} void add(int a,int b) {
if(!b)return;
pre[++tot]=now[a];
now[a]=tot,son[tot]=b;
} int cmp(int pos1,int pos2) {
if(a[pos1]<a[pos2])return pos1;
return pos2;
} void make_st() {
for(int i=1;i<20;i++)
for(int j=1;j+(1<<i)-1<=n;j++)
for(int k=0;k<2;k++)
f[i][j][k]=cmp(f[i-1][j][k],f[i-1][j+(1<<(i-1))][k]);
} int solve(int l,int r,int opt) {
if(r<l)return 0;
if(l+1==r) {
node[++cnt]=make_pair(a[l],a[r]);
return cnt;
}
int x=log2(r-l+1);
int pos=cmp(f[x][l][opt],f[x][r-(1<<x)+1][opt]);
x=log2(r-pos+1);
int tmp=cmp(f[x][pos][opt^1],f[x][r-(1<<x)+1][opt^1]);
node[++cnt]=make_pair(a[pos],a[tmp]);x=cnt;
add(x,solve(l,pos-1,opt));
add(x,solve(pos+1,tmp-1,opt^1));
add(x,solve(tmp+1,r,opt));
return x;
} struct Heap {
int len;
int tree[maxn]; void ins(int u) {
tree[++len]=u;
int pos=len;
while(pos>1) {
if(node[tree[pos]]<node[tree[pos>>1]])
swap(tree[pos],tree[pos>>1]),pos>>=1;
else break;
}
} int pop() {
int res=tree[1];
tree[1]=tree[len--];
int pos=1,son=2;
while(son<=len) {
if(son<len&&node[tree[son|1]]<node[tree[son]])son|=1;
if(node[tree[son]]<node[tree[pos]])
swap(tree[pos],tree[son]),pos=son,son=pos<<1;
else break;
}
return res;
}
}H; void make_ans() {
H.ins(rt);
while(H.len) {
int u=H.pop();printf("%d %d ",node[u].fr,node[u].sc);
for(int p=now[u];p;p=pre[p])
H.ins(son[p]);
}
} int main() {
n=read();a[0]=2e9;
for(int i=1;i<=n;i++)
a[i]=read(),f[0][i][i&1]=i;
make_st();
rt=solve(1,n,1);
make_ans();
return 0;
}

AtCoder Regular Contest 080 E:Young Maids的更多相关文章

  1. AtCoder Regular Contest 080 E - Young Maids

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

  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 D - Grid Coloring

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

  4. AtCoder Regular Contest 080 C - 4-adjacent

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

  5. AtCoder Regular Contest 080 [CDEF]

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

  6. AtCoder Regular Contest 080

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

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

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

  8. AtCoder Regular Contest 072 E:Alice in linear land

    题目传送门:https://arc072.contest.atcoder.jp/tasks/arc072_c 题目翻译 给你一个数组\(D\),然后给你一个操作序列\(d\),每次操作可以将\(D\) ...

  9. AtCoder Regular Contest 074 E:RGB Sequence

    题目传送门:https://arc074.contest.atcoder.jp/tasks/arc074_c 题目翻译 给你一行\(n\)个格子,你需要给每个格子填红绿蓝三色之一,并且同时满足\(m\ ...

随机推荐

  1. 写一段代码,判断一个包括'{','[','(',')',']','}'的表达式是否合法(注意看样例的合法规则。) 给定一个表达式A,请返回一个bool值,代表它是否合法。

    这道题比较奇怪,它的匹配规则并不是我们平时想想的那种匹配规则,例如:平时的匹配规则是().{}.[]才能匹配,本题中(和} .].)都能匹配.所以做题时要好好审题.另外,本题中给的测试用例是错误的. ...

  2. JDK设置Encoding编码格式

    执行JAVA程序报错内容如下: java.lang.IllegalStateException: The Java Virtual Machine has not been configured to ...

  3. 800元组装一台3D打印机全教程流程

    我最近正好要组装一台新的reprap的kossel delta型开源3d打印机,这台机器性价比非常高,具有速度快,静音,三臂并联结构,扩展性强,便宜的特点.图纸啥的都有,只是用到mega2560和ra ...

  4. Android TextView setText卡顿问题

    TextView 是经常使用控件之中的一个,最经常使用的方法是setText()  . 可是 我们在显示大量的文本的时候,使用setText还是会有一些性能的问题. 这篇文章 关于TextView的s ...

  5. 【EDAS问题】轻量级EDAS部署hsf服务出现找不到类的解决方案

    本地运行轻量级EDAS调用服务的时候报错如下: 2018-01-08 13:16:58.029 WARN [http-bio-8090-exec-8:t.hsf] [RPC Protocol call ...

  6. Trie树,又称单词查找树、字典

    在百度或淘宝搜索时,每输入字符都会出现搜索建议,比如输入“北京”,搜索框下面会以北京为前缀,展示“北京爱情故事”.“北京公交”.“北京医院”等等搜索词.实现这类技术后台所采用的数据结构是什么?[中国某 ...

  7. HTML--2图片热点,网页划区,拼接,表单

    图片热点: 规划出图片上的一个区域,可以做出超链接,直接点击图片区域就可以完成跳转的效果. 示例: 网页划区: 在一个网页里,规划出一个区域用来展示另一个网页的内容. 示例: 网页的拼接: 在一个网络 ...

  8. Python中的注解“@” 、Java 注解

    https://blog.csdn.net/u013474436/article/details/75675113 https://blog.csdn.net/briblue/article/deta ...

  9. 九度OJ 1044:Pre-Post(先序后序) (n叉树、递归)

    时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:701 解决:398 题目描述: We are all familiar with pre-order, in-order and post- ...

  10. 云服务器 ECS Linux CentOS 修改内核引导顺序

    由于 CentOS 7 使用 grub2 作为引导程序,所以和 CentOS 6 有所不同,并不是修改 /etc/grub.conf 来修改启动项,需要如下操作: 1. 查看系统内部有多少个内核: c ...