【AtCoder Regular Contest 080E】Young Maids [堆][线段树]
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 [堆][线段树]的更多相关文章
- Atcoder Grand Contest 023 E - Inversions(线段树+扫描线)
洛谷题面传送门 & Atcoder 题面传送门 毒瘤 jxd 作业-- 首先我们不能直接对所有排列计算贡献对吧,这样复杂度肯定吃不消,因此我们考虑对每两个位置 \(x,y(x<y)\), ...
- 【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 ...
- AtCoder Regular Contest 088 E - Papple Sort(树状数组+结论)
结论:每次把字符丢到最外面最优,用树状数组统计答案,把字符放到最外边后可以当成消失了,直接在树状数组上删掉就好. 感性理解是把字符丢到中间会增加其他字符的移动次数,但是丢到外面不会,所以是正确的. # ...
- AtCoder Regular Contest 069 F Flags 二分,2-sat,线段树优化建图
AtCoder Regular Contest 069 F Flags 二分,2-sat,线段树优化建图 链接 AtCoder 大意 在数轴上放上n个点,点i可能的位置有\(x_i\)或者\(y_i\ ...
- AtCoder Regular Contest 061
AtCoder Regular Contest 061 C.Many Formulas 题意 给长度不超过\(10\)且由\(0\)到\(9\)数字组成的串S. 可以在两数字间放\(+\)号. 求所有 ...
- AtCoder Regular Contest 094 (ARC094) CDE题解
原文链接http://www.cnblogs.com/zhouzhendong/p/8735114.html $AtCoder\ Regular\ Contest\ 094(ARC094)\ CDE$ ...
- AtCoder Regular Contest 092
AtCoder Regular Contest 092 C - 2D Plane 2N Points 题意: 二维平面上给了\(2N\)个点,其中\(N\)个是\(A\)类点,\(N\)个是\(B\) ...
- AtCoder Regular Contest 093
AtCoder Regular Contest 093 C - Traveling Plan 题意: 给定n个点,求出删去i号点时,按顺序从起点到一号点走到n号点最后回到起点所走的路程是多少. \(n ...
- AtCoder Regular Contest 094
AtCoder Regular Contest 094 C - Same Integers 题意: 给定\(a,b,c\)三个数,可以进行两个操作:1.把一个数+2:2.把任意两个数+1.求最少需要几 ...
随机推荐
- docker-py安装
linux: pip install docker-py
- 斑马条码打印机GK888T打印标签是间隔的 ,不是连续的
有间断的标签纸和连续的标签纸是两种不同的纸张类型, 打印机的标签感应器需要工作在不同的模式来跟踪感应它们. 打印机正确感应纸张才不会红灯闪烁,打印的内容才按文件设计打印到标签的对应位置上. 所以要在驱 ...
- 初入码田--ASP.NET MVC4 Web应用之创建一个空白的MVC应用程序
初入码田--ASP.NET MVC4 Web应用开发之一 实现简单的登录 初入码田--ASP.NET MVC4 Web应用开发之二 实现简单的增删改查 2016-07-29 在此之前,需要一台电脑( ...
- Dubbo学习(四) dubbo的特点,8种通信协议之对比
一.dubbo的特性 (1) 连通性: 注册中心负责服务地址的注册与查找,相当于目录服务,服务提供者和消费者只在启动时与注册中心交互,注册中心不转发请求,压力较小 监控中心负责统计各服务调用次数,调用 ...
- Flyway学习笔记
Flyway做为database migration开源工具,功能上像是git.svn这种代码版本控制.google搜索database migration,或者针对性更强些搜索database mi ...
- bzoj2302-Problem c
题意 有 \(n\) 个人,从 1 到 \(i\) 编号.给每个人一个值 \(a_i\) ,他们会按编号从小到大进行如下操作:查看 \(a_i\) 有没有人,若没有就坐进去,否则查看 \(a_i+1\ ...
- css 样式 文字过长 换行处理方法
css强制换行.强制不换行及自动换行的写法 css强制不换行 div{white-space:nowrap;} css自动换行 div{ word-wrap: break-word; word-bre ...
- 【大数据】关于Kafka的进一步理解
前置: 文件host 192.168.11.13 192.168.11.14 192.168.11.30 脚本init_kafka.sh #!/bin/bash source /etc/profile ...
- 【刷题】BZOJ 4031 [HEOI2015]小Z的房间
Description 你突然有了一个大房子,房子里面有一些房间.事实上,你的房子可以看做是一个包含n*m个格子的格状矩形,每个格子是一个房间或者是一个柱子.在一开始的时候,相邻的格子之间都有墙隔着. ...
- 【转】嵌入式Linux驱动面试题三道
题一: Linux设备中字符设备与块设备有什么主要的区别? 字符设备:字符设备是个能够像字节流(类似文件)一样被访问的设备,由字符设备驱动程序来实现这种特性.字符设备驱动程序通常至少实现open,cl ...