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

题目大意

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

题解

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

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

代码

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+5;
int n,a[N],b[N];
struct Point{int data,loc;};
bool operator < (const Point a,const Point b){return a.data<b.data;}
struct Seg_Tree
{
struct Node{Point data;}tr[N<<2];
void up(int u){tr[u].data=min(tr[u<<1].data,tr[u<<1|1].data);}
void build(int u,int l,int r,int a[])
{
if(l==r)
{
tr[u].data.data=a[l];
tr[u].data.loc=l;
return ;
}
int mid=(l+r)>>1;
build(u<<1,l,mid,a);
build(u<<1|1,mid+1,r,a);
up(u);
}
void chg(int u,int l,int r,int x)
{
if(l==r){tr[u].data.data=1e9+7;return ;}
int mid=(l+r)>>1;
if(x<=mid) chg(u<<1,l,mid,x);
else chg(u<<1|1,mid+1,r,x);
up(u);
}
Point query(int u,int l,int r,int x,int y)
{
if(x<=l&&r<=y) return tr[u].data;
int mid=(l+r)>>1;Point res={1000000007,0};
if(x<=mid) res=min(res,query(u<<1,l,mid,x,y));
if(y>mid) res=min(res,query(u<<1|1,mid+1,r,x,y));
return res;
}
}t[2];//0为偶,1为奇
struct Data{int l,r;Point data;};
bool operator < (const Data a,const Data b){return a.data.data>b.data.data;}
priority_queue<Data> q;
vector<int> res;
int main()
{
cin>>n;
for(int i=1,x;i<=n;++i)
{
scanf("%d",&x);
if(i&1) a[i]=1e9+7,b[i]=x;
else a[i]=x,b[i]=1e9+7;
}
t[0].build(1,1,n,a);
t[1].build(1,1,n,b);
Data tmp;
tmp.l=1,tmp.r=n;
tmp.data=t[1].query(1,1,n,1,n);
q.push(tmp);
for(int i=1;i<=n/2;++i)
{
tmp=q.top(),q.pop();
int tag=tmp.l%2;
// printf("%d\n",tag);
Point L=tmp.data,R=t[tag^1].query(1,1,n,L.loc+1,tmp.r);
// printf("%d %d %d %d\n",tmp.l,tmp.r,L.data,R.data);
res.push_back(L.data),res.push_back(R.data);
Data now;
now.l=tmp.l,now.r=L.loc-1;
if(now.l<=now.r)
{
now.data=t[tag].query(1,1,n,now.l,now.r);
q.push(now);
}
now.l=L.loc+1,now.r=R.loc-1;
if(now.l<=now.r)
{
now.data=t[tag^1].query(1,1,n,now.l,now.r);
q.push(now);
}
now.l=R.loc+1,now.r=tmp.r;
if(now.l<=now.r)
{
now.data=t[tag].query(1,1,n,now.l,now.r);
q.push(now);
}
}
for(int i=0;i<(int)res.size();++i) printf("%d ",res[i]);
printf("\n");
return 0;
}

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. linux 进程间通信 共享内存 mmap

    共享内存可以说是最有用的进程间通信方式,也是最快的IPC形式.两个不同进程A.B共享内存的意思是,同一块物理内存被映射到进程A.B各自的进程地址空间.进程A可以即时看到进程B对共享内存中数据的更新,反 ...

  2. Golang调度器GMP原理与调度全分析(转 侵 删)

    该文章主要详细具体的介绍Goroutine调度器过程及原理,包括如下几个章节. 第一章 Golang调度器的由来 第二章 Goroutine调度器的GMP模型及设计思想 第三章 Goroutine调度 ...

  3. 如何开发一个maven插件

    maven是当下最流行的项目管理工具,其丰富的插件为我们的工作带来了很大的便利. 但是在一些情况下,开源的插件并不能完全满足我们的需求,我们需要自己创建插件,本文就从0开始带大家一起创建自己的插件. ...

  4. NOIP前一些题目的理解

    ZYB和售货机(图论,环) 题目链接 个人感觉这道题与基环树没有任何关系,你会发现,每个点最多只有一个入度和出度,所以只能是链或环. 还有就是本题的突破点就在于正确建图,题目的限制保证每个点的入度不大 ...

  5. Ceph根据Crush位置读取数据

    前言 在ceph研发群里面看到一个cepher在问关于怎么读取ceph的副本的问题,这个功能应该在2012年的时候,我们公司的研发就修改了代码去实现这个功能,只是当时的硬件条件所限,以及本身的稳定性问 ...

  6. java 连接sqlserver

    db.properties 文件 driver=com.microsoft.sqlserver.jdbc.SQLServerDriver url=jdbc:sqlserver://10.1.1.19: ...

  7. [PHP安全特性学习]strcmp()函数安全漏洞

    简介 PHP函数的安全特性-strcmp() 函数 php-strcmp()函数 PHP strcmp() 函数 strcmp() 函数比较两个字符串. 注释:strcmp() 函数是二进制安全的,且 ...

  8. 苹果电脑下载器Folx有没有自动下载功能

    苹果电脑下载器Folx提供了多项自动化任务功能,供用户更好地利用电脑的空闲时间,减少自己直接参与下载的时间,从而提升下载效率. 接下来,小编将重点介绍Folx自动化工作中的任务完成后的自动化工作.自动 ...

  9. 利用perspective 和 transform 里面的几个参数来实现旋转照片墙

    旋转照片墙 首先,来看下,是什么效果吧,上效果图 ↓ 其实这个东西,很容易制作,先说下思路, 把照片都给叠在一起,然后 rotateY 旋转,给每张图片 旋转不一样的角度能构成一圈, 然后transl ...

  10. So Easy! HDU - 4565

    易知,有\(S_n = \lceil{a + \sqrt{b}}\rceil ^ n\) \(\because a ^ 2 - 1 < b < a ^ 2\) \(\therefore a ...