Young Maids

Time Limit: 50 Sec  Memory Limit: 512 MB

Description

  给定一个排列,每次选出相邻的两个放在队头,要求字典序最小。

Input

  第一行一个整数n,第二行n个数表示这个排列。

Output

  n个数表示答案。

Sample Input

  8
  4 6 3 2 8 5 7 1

Sample Output

  3 1 2 7 4 6 8 5

HINT

  n%2=0,2 <= n <= 2e5

Solution

  倒着考虑。
  我们维护一个小根堆,堆里面存[l, r, val],表示在区间[l, r]中选择两个元素,第一个元素A的权值为val(保证合法),以val为第一关键字

  那么显然,我们每次选出堆顶进行操作

  显然,若我们取走了A,B(pos[A] < pos[B])[l,r]就被拆成了 [l,A-1], [A+1,B-1], [B+1,r],我们要保证每一个区间长度都是偶数
  那么只要有,pos[A]%2 == pos[l]%2,pos[B]%2 == pos[r]%2
  又由于我们每次减少两个数,所以这样显然可以保证 pos[B]-pos[A]+1 % 2 == 0

  现在问题就是怎么求出A、B具体是那两个数,显然写个线段树维护一下 某段区间内奇数/偶数位置的min_val和所在的pos即可。

Code

 #include<iostream>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<queue>
using namespace std;
typedef long long s64; const int ONE = ;
const int INF = ; int get()
{
int res = , Q = ; char c;
while( (c = getchar()) < || c > )
if(c == '-') Q = -;
if(Q) res = c - ;
while( (c = getchar()) >= && c <= )
res = res * + c - ;
return res * Q;
} int n;
int a[ONE]; struct point
{
int id, val;
friend bool operator <(point a, point b)
{
if(a.val != b.val) return a.val < b.val;
return a.id < b.id;
}
};
point res; namespace Seg
{
struct power {point odd, eve;} Node[ONE * ]; void Build(int i, int l, int r)
{
Node[i].odd.val = Node[i].eve.val = INF;
if(l == r)
{
if(l & ) Node[i].odd = (point){l, a[l]};
else Node[i].eve = (point){l, a[l]};
return;
}
int mid = l + r >> ;
Build(i << , l, mid), Build(i << | , mid + , r);
Node[i].odd = min(Node[i << ].odd, Node[i << | ].odd);
Node[i].eve = min(Node[i << ].eve, Node[i << | ].eve);
} void Query(int i, int l, int r, int L, int R, int opt)
{
if(L <= l && r <= R)
{
if(opt == ) res = min(res, Node[i].odd);
else res = min (res, Node[i].eve);
return;
}
int mid = l + r >> ;
if(L <= mid) Query(i << , l, mid, L, R, opt);
if(mid + <= R) Query(i << | , mid + , r, L, R, opt);
}
} struct power
{
int l, r, val;
bool operator <(power a) const
{
if(a.val != val) return a.val < val;
return a.l < l;
}
};
priority_queue <power> q; point Get(int l, int r, int opt)
{
res = (point){n + , INF};
Seg::Query(, , n, l, r, opt);
return res;
} void Add(int l, int r)
{
if(l > r) return;
q.push((power){l, r, Get(l, r, l % ).val});
} int main()
{
n = get();
for(int i = ; i <= n; i++)
a[i] = get(); Seg::Build(, , n);
Add(, n); for(int i = ; i <= n / ; i++)
{
power u = q.top(); q.pop();
point A = Get(u.l, u.r - , u.l % );
point B = Get(A.id + , u.r, u.r % );
printf("%d %d ", A.val, B.val); Add(u.l, A.id - ), Add(A.id + , B.id - ), Add(B.id + , u.r);
}
}

【AtCoder Regular Contest 080E】Young Maids [堆][线段树]的更多相关文章

  1. Atcoder Grand Contest 023 E - Inversions(线段树+扫描线)

    洛谷题面传送门 & Atcoder 题面传送门 毒瘤 jxd 作业-- 首先我们不能直接对所有排列计算贡献对吧,这样复杂度肯定吃不消,因此我们考虑对每两个位置 \(x,y(x<y)\), ...

  2. 【AtCoder Grand Contest 001F】Wide Swap [线段树][拓扑]

    Wide Swap Time Limit: 50 Sec  Memory Limit: 512 MB Description Input Output Sample Input 8 3 4 5 7 8 ...

  3. AtCoder Regular Contest 088 E - Papple Sort(树状数组+结论)

    结论:每次把字符丢到最外面最优,用树状数组统计答案,把字符放到最外边后可以当成消失了,直接在树状数组上删掉就好. 感性理解是把字符丢到中间会增加其他字符的移动次数,但是丢到外面不会,所以是正确的. # ...

  4. AtCoder Regular Contest 069 F Flags 二分,2-sat,线段树优化建图

    AtCoder Regular Contest 069 F Flags 二分,2-sat,线段树优化建图 链接 AtCoder 大意 在数轴上放上n个点,点i可能的位置有\(x_i\)或者\(y_i\ ...

  5. AtCoder Regular Contest 061

    AtCoder Regular Contest 061 C.Many Formulas 题意 给长度不超过\(10\)且由\(0\)到\(9\)数字组成的串S. 可以在两数字间放\(+\)号. 求所有 ...

  6. AtCoder Regular Contest 094 (ARC094) CDE题解

    原文链接http://www.cnblogs.com/zhouzhendong/p/8735114.html $AtCoder\ Regular\ Contest\ 094(ARC094)\ CDE$ ...

  7. AtCoder Regular Contest 092

    AtCoder Regular Contest 092 C - 2D Plane 2N Points 题意: 二维平面上给了\(2N\)个点,其中\(N\)个是\(A\)类点,\(N\)个是\(B\) ...

  8. AtCoder Regular Contest 093

    AtCoder Regular Contest 093 C - Traveling Plan 题意: 给定n个点,求出删去i号点时,按顺序从起点到一号点走到n号点最后回到起点所走的路程是多少. \(n ...

  9. AtCoder Regular Contest 094

    AtCoder Regular Contest 094 C - Same Integers 题意: 给定\(a,b,c\)三个数,可以进行两个操作:1.把一个数+2:2.把任意两个数+1.求最少需要几 ...

随机推荐

  1. js+Canvas 利用js 实现浏览器保存图片到本地

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  2. 通过cmd命令安装、卸载、启动和停止Windows Service(InstallUtil.exe)

    步骤: 1.运行--〉cmd:打开cmd命令框 2.在命令行里定位到InstallUtil.exe所在的位置 InstallUtil.exe 默认的安装位置是在C:/Windows/Microsoft ...

  3. 【硬件】- 英特尔CPU命名规则

    前言 一款Intel CPU的命名,一般由5个部分组成:品牌,品牌标识符,Gen标识,SKU数值,产品线后缀. 以下图为例: 品牌 英特尔旗下处理器有许多子品牌,包括我们熟悉的凌动(ATOM).赛扬( ...

  4. uva 11525(线段树)

    题目链接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...

  5. 罗辑思维CEO脱不花:关于工作和成长,这是我的121条具体建议

    1 关于面对批评 01. 没有人对被批评感到高兴.如果有,TA撒谎. 02. 面对批评,得体的第一反应是“不急于解释,不反唇相讥”. 03. 每天,或者最长每周养成习惯,把自己存在的问题和造成的麻烦用 ...

  6. 【HDU4336】Card Collector(Min-Max容斥)

    [HDU4336]Card Collector(Min-Max容斥) 题面 Vjudge 题解 原来似乎写过一种状压的做法,然后空间复杂度很不优秀. 今天来补一种神奇的方法. 给定集合\(S\),设\ ...

  7. MySQL 第六篇:数据备份、pymysql模块

    一 IDE工具介绍 生产环境还是推荐使用mysql命令行,但为了方便我们测试,可以使用IDE工具 下载链接:https://pan.baidu.com/s/1O8hXkdRK5_EVHZwNPwjCB ...

  8. Python 爬虫入门(二)—— IP代理使用

    上一节,大概讲述了Python 爬虫的编写流程, 从这节开始主要解决如何突破在爬取的过程中限制.比如,IP.JS.验证码等.这节主要讲利用IP代理突破. 1.关于代理 简单的说,代理就是换个身份.网络 ...

  9. android studio 代码混淆如何忽略第三方jar包

    日前在打包混淆包含第三方jar包的Android studio项目时 报出了各种错误,但是debug版本却能正常运行,于是怀疑android studio 打包的时候把第三方jar包给混淆了,第三方j ...

  10. Service Fabric Cluster Manager

    作者:潘罡 (Van Pan)@ Microsoft 我们回到Service Fabric最底层的话题,谈谈Service Fabric是怎么工作的. 首先,我们回到下面的文档,看看Service F ...