【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.求最少需要几 ...
随机推荐
- My复利计算程序测试报告
My复利计算程序测试报告 4.0 单元测试----------------------------- 要求: 对我们和复利计算程序,写单元测试. 有哪些场景? 期待的返回值 写测试程序. 运行测试. ...
- startActivityForResult()的用法(超好用啊)
最近做的一个小东西遇到这样的情况,我从一个页面MainActivity修改一些内容,需要跳转到一个新的EditActivity去做修改操作,修改完成后就回到之前的MainActivity,因为信息被修 ...
- windows结束端口对应的进程
netstat -ano |findstr " //window查看端口占用 taskkill /pid 54828taskkill /F /pid 54828 //强制中止 转载请注明博客 ...
- firewall和iptables
防火墙有这三种方式,firewalld.iptables.ebtables,现在的centOS7使用的是firewalld. 下面是一些总结: 查看当前firewalld的状态 firewall-cm ...
- HDU4436_str2int
很好的一个题目.对于理解后缀自动机很有用. 题目给你若干数字串,总长度不超过100000,任意一个串的任意一个子串都可以拿出来单独的作为一个数字.同一个数字只算一次. 问所有不同数字的和为多少? 嗯嗯 ...
- iOS 一些常见问题
1.屏幕横屏时 xib上拖拉的控件不会跟着横过来: 是因为在主文件面里的 main interface 方框里的main 没有删除: 2.运行出现你没有权限 : 清理一下: 3.将对象转成字符串: / ...
- P4645 [COCI2006-2007 Contest#3] BICIKLI
题意翻译 给定一个有向图,n个点,m条边.请问,1号点到2号点有多少条路径?如果有无限多条,输出inf,如果有限,输出答案模10^9的余数. 两点之间可能有重边,需要看成是不同的路径. 题目描述 A ...
- hihocoder1711 评论框排版[并查集+set]
#include <cstdio> #include <iostream> #include <set> using namespace std; ; struct ...
- BGP的那些安全痛点(转)
0x00 BGP(RFC 1771. RFC 4271)定义 全称是Border Gateway Protocol, 对应中文是边界网关协议,最新版本是BGPv4. BGP是互联网上一个核心的互联网去 ...
- 特征降维之PCA
目录 PCA思想 问题形式化表述 PCA之协方差矩阵 协方差定义 矩阵-特征值 PCA运算步骤 PCA理论解释 最大方差理论 性质 参数k的选取 数据重建 主观理解 应用 代码示例 PCA思想 PCA ...