【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.求最少需要几 ...
随机推荐
- 评论各组alpha发布
单纯从用户和体验者的角度来评价. 天天向上组的连连看游戏和新锋组的俄罗斯方块游戏,从alpha发布的成果完成度来看,两个游戏现在都可以玩,但连连看的完成度更高,可选背景,可选音乐.俄罗斯方块还有其他界 ...
- [转帖] .net 2.1 是 LTS长期支持版本.
[翻译] .NET Core 2.1 发布 原文: Announcing .NET Core 2.1 我们很高兴可以发布 .NET Core 2.1.这次更新包括对性能的改进,对运行时和工具的改进 ...
- linux 配置文件(启动文件、环境文件)启动顺序
1.登录shell 登录shell时,linux会按一定规则读取启动几个配置文件: /ect/profile $HOME/.bash_profile $HOME/.bashrc $HOME/.bash ...
- 【原创】c# Winform 使用 web 的UrlEncode/UrlDecode 方法
1.先 右键引用,添加 System.Web 数据集 2.语句如下 string s= System.Web.HttpUtility.UrlEncode("123", System ...
- FastDFS分布式存储
分布式存储分类 通用分布式存储:mogilefs, fastdfs, ...(无文件系统接口, 通过API访问) 专用分布式存储:即分布式文件系统, moosefs, ...(有文件系统接口) GFS ...
- MySQL总结小妙招
mysql5.7版本,免登陆修改管理员密码: vim /etc/my.cnf 加入skip-grant-tables,重启MySQL 终端输入 mysql ,直接登录MySQL数据库,然后use my ...
- 移动端图片轮播—swipe滑动插件
swipe是一个轻量级的移动滑动组件,它可以支持精确的触滑移动操作,能解决移动端对滑动的需求. swipe插件的使用主要有四大块: 一.html <div id='slider' class=' ...
- HYSBZ(BZOJ) 4300 绝世好题(位运算,递推)
HYSBZ(BZOJ) 4300 绝世好题(位运算,递推) Description 给定一个长度为n的数列ai,求ai的子序列bi的最长长度,满足bi&bi-1!=0(2<=i<= ...
- mysql 优化之查询缓存(mysql8已经废弃这个功能)
对于缓存,一般人想到的是 redis.memcache 这些内存型的缓存. 但是实际上 mysql 也提供了缓存,mysql 里面的缓存是查询缓存,可以把我们查询过的语句缓存下来,下一次查询的时候有可 ...
- shell 变量定义使用
shell 中变量的几种类型: 1.局部变量:只在当前 shell 可用的变量, 2.环境变量:当前 shell 的子进程也可用的变量 3.shell 变量:一些由 shell 设置的特殊变量,如:$ ...