【递归】【线段树】【堆】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在当前 ...
随机推荐
- peewee外键性能问题
# 转载自:https://www.cnblogs.com/miaojiyao/articles/5217757.html 下面讨论一下用peewee的些许提高性能的方法. 避免N+1查询 N+1查询 ...
- Exploring Qualcomm's TrustZone Implementation
转自 http://bits-please.blogspot.com/2015/08 (需要FQ, 狗日的墙) In this blog post, we'll be exploring Qua ...
- swift中闭包的循环引用
首先我们先创造一个循环引用 var nameB:(()->())? override func viewDidLoad() { super.viewDidLoad() let bu = UIBu ...
- DevExpress.XtraTreeList 小结
搞了半天才绑定好,没有弄清楚父子之间的关系 <dx:ASPxTreeList ID="ASPxTreeList1" runat="server" Auto ...
- springmvc中输出字符串
/** * 输出文字 * @param response * @param s */ public static void responseOut(HttpServletResponse respon ...
- mycncart 前台代码跟踪
1.进入根目录的入口文件,index.php require_once(DIR_SYSTEM . 'startup.php');//最为重要的一步 start('catalog');//执行了这个方法 ...
- java生成缩略图,旋转,水印,截图
转自:http://rensanning.iteye.com/blog/1545708 感谢,方便自己查看
- Mybatis学习—XML映射文件
总结自 Mybatis官方中文文档 Mapper XML 文件 MyBatis 的真正强大在于它的映射语句,也是它的魔力所在.由于它的异常强大,映射器的 XML 文件就显得相对简单.如果拿它跟具有相同 ...
- ASP.NET MVC 视图学习,纯干货
最近用MVC专门为自己做了一个网站,用来记录文章心情和日记.加上和同事的一些交流感觉颇深.所以想把13年买的MVC 4高级编程重新看一遍,记录一些东西,以后应该用的到.视图总是被控制器渲染,因为控制器 ...
- golang实现mysql数据库备份
背景 navicat是mysql可视化工具中最棒的,但是,在处理视图的导入导出方面,它是按照视图名称的字母顺序来处理的,若视图存在依赖,在导入过程中就会报错.前面已经用python写了一个,但在使用过 ...