Atcoder arc080E Young Maids(线段树+优先队列)
给出一个n排列,每次可以选择相邻的两个数字放在新的排列首部,问最后形成的新的排列字典序最小是?
考虑新排列的第一个数字,则应是下标为奇数的最小数,下标不妨设为i。第二个数字应该下标大于i且为偶数的最小数,不妨设为j。
那么这样就将[1,n]新分割成了三个区间[1,i-1],[i+1,j-1],[j+1,n]。
用线段树实现查询操作。用优先队列维护区间的最优值。
时间复杂度O(nlogn).
# include <cstdio>
# include <cstring>
# include <cstdlib>
# include <iostream>
# include <vector>
# include <queue>
# include <stack>
# include <map>
# include <bitset>
# include <set>
# include <cmath>
# include <algorithm>
using namespace std;
# define lowbit(x) ((x)&(-x))
# define pi acos(-1.0)
# define eps 1e-
# define MOD
# define INF
# define mem(a,b) memset(a,b,sizeof(a))
# define FOR(i,a,n) for(int i=a; i<=n; ++i)
# define FDR(i,a,n) for(int i=a; i>=n; --i)
# define bug puts("H");
# define lch p<<,l,mid
# define rch p<<|,mid+,r
# define mp make_pair
# define pb push_back
typedef pair<int,int> PII;
typedef vector<int> VI;
# pragma comment(linker, "/STACK:1024000000,1024000000")
typedef long long LL;
inline int Scan() {
int x=,f=; char ch=getchar();
while(ch<''||ch>''){if(ch=='-') f=-; ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-''; ch=getchar();}
return x*f;
}
inline void Out(int a) {
if(a<) {putchar('-'); a=-a;}
if(a>=) Out(a/);
putchar(a%+'');
}
const int N=;
//Code begin.... struct qnode{
int l, r, vl, vr;
qnode(int _l=, int _r=, int _vl=, int _vr=):l(_l),r(_r),vl(_vl),vr(_vr){}
bool operator<(const qnode &m)const{return vl>m.vl;}
};
priority_queue<qnode>que;
struct Seg{int odd, even;}seg[N<<];
int a[N], id[N];
VI ans; void push_up(int p){
seg[p].even=min(seg[p<<].even, seg[p<<|].even);
seg[p].odd=min(seg[p<<].odd, seg[p<<|].odd);
}
void init(int p, int l, int r){
if (l<r) {
int mid=(l+r)>>;
init(lch); init(rch); push_up(p);
}
else {
if (l&) seg[p].even=a[l], seg[p].odd=INF;
else seg[p].odd=a[l], seg[p].even=INF;
}
}
int query(int p, int l, int r, int L, int R, int flag){
if (L>r||R<l) return INF;
if (L<=l&&R>=r) return flag?seg[p].even:seg[p].odd;
else {
int mid=(l+r)>>;
return min(query(lch,L,R,flag),query(rch,L,R,flag));
}
}
int main ()
{
int n, x, y, l, r, ll;
qnode tmp;
scanf("%d",&n);
FOR(i,,n) scanf("%d",a+i), id[a[i]]=i;
init(,,n);
x=query(,,n,,n,); l=id[x]; y=query(,,n,l+,n,);
que.push(qnode(,n,x,y));
FOR(i,,n/) {
tmp=que.top(); que.pop();
ans.pb(tmp.vl); ans.pb(tmp.vr);
l=id[tmp.vl]; r=id[tmp.vr];
if (tmp.l<l-) {
x=query(,,n,tmp.l,l-,tmp.l&); ll=id[x]; y=query(,,n,ll+,l-,(l-)&);
que.push(qnode(tmp.l,l-,x,y));
}
if (l+<r-) {
x=query(,,n,l+,r-,(l+)&); ll=id[x]; y=query(,,n,ll+,r-,(r-)&);
que.push(qnode(l+,r-,x,y));
}
if (r+<tmp.r) {
x=query(,,n,r+,tmp.r,(r+)&); ll=id[x]; y=query(,,n,ll+,tmp.r,tmp.r&);
que.push(qnode(r+,tmp.r,x,y));
}
}
for (int i=; i<ans.size(); ++i) printf(i==?"%d":" %d",ans[i]);
putchar('\n');
return ;
}
Atcoder arc080E Young Maids(线段树+优先队列)的更多相关文章
- AtCoder Regular Contest 080 (ARC080) E - Young Maids 线段树 堆
原文链接http://www.cnblogs.com/zhouzhendong/p/8934377.html 题目传送门 - ARC080 E - Young Maids 题意 给定一个长度为$n$的 ...
- 【未完】训练赛20190304:KMP+树状数组+线段树+优先队列
头炸了啊,只做出L题,前两天刚看的Shawn zhou的博客学习的,幸亏看了啊,否则就爆零了,发现题目都是经典题,线段树,KMP,我都没看过,最近又在复习考研,真后悔大一大二没好好学习啊,得抽时间好好 ...
- AtCoder AGC001F Wide Swap (线段树、拓扑排序)
题目链接: https://atcoder.jp/contests/agc001/tasks/agc001_f 题解: 先变成排列的逆,要求\(1\)的位置最小,其次\(2\)的位置最小,依次排下去( ...
- 【AtCoder Regular Contest 080E】Young Maids [堆][线段树]
Young Maids Time Limit: 50 Sec Memory Limit: 512 MB Description 给定一个排列,每次选出相邻的两个放在队头,要求字典序最小. Input ...
- 【递归】【线段树】【堆】AtCoder Regular Contest 080 E - Young Maids
给你一个1~n的排列p,n是偶数,每次从中任选一对相邻的数出来,插到排列q的开头,如此循环,问你所能得到的字典序最小的排列q. 我们先确定q开头的两个数q1,q2,q1一定是p的奇数位的最小的数,而q ...
- “盛大游戏杯”第15届上海大学程序设计联赛夏季赛暨上海高校金马五校赛题解&&源码【A,水,B,水,C,水,D,快速幂,E,优先队列,F,暴力,G,贪心+排序,H,STL乱搞,I,尼姆博弈,J,差分dp,K,二分+排序,L,矩阵快速幂,M,线段树区间更新+Lazy思想,N,超级快速幂+扩展欧里几德,O,BFS】
黑白图像直方图 发布时间: 2017年7月9日 18:30 最后更新: 2017年7月10日 21:08 时间限制: 1000ms 内存限制: 128M 描述 在一个矩形的灰度图像上,每个 ...
- HDU 5700 优先队列(或者multiset) 或 线段树
题目大意:有n个区间,求k个区间,使得这k个区间相交的区间内数字之和最大.数列的数字均>=0 优先队列思路: 按照左端点sort,然后枚举左端点,假设他被覆盖过k次,然后用优先队列来维护最右端即 ...
- AtCoder Regular Contest 080 E - Young Maids
地址:http://arc080.contest.atcoder.jp/tasks/arc080_c 题目: E - Young Maids Time limit : 2sec / Memory li ...
- hdu 4302 Holedox Eating(优先队列/线段树)
题意:一只蚂蚁位与原点,在x轴正半轴上会不时地出现一些蛋糕,蚂蚁每次想吃蛋糕时选取最近的去吃,如果前后距离相同,则吃眼前的那一块(即方向为蚂蚁的正前),求最后蚂蚁行进距离. 思路:优先队列q存储蚂蚁前 ...
随机推荐
- JavaScript——历史与简介
上一篇博文距离现在已经四个月了,一直想写些什么无奈工作比较忙碌.我的恩师老王在毕业聚餐那天带着一声酒气告诉我一定要把博客坚持写下去,所以今天下决心要开始这个新的篇章. 之所以想要从头写一个关于Java ...
- 六种流行的语言大餐---C、C++、python、Java、php、C#你更喜欢哪一个呢?
引言 鉴于五一期间超大的人流量,LZ思来想去,最终还是选择蜗居在自己的出租屋.无聊之际,当然不能忘了做点什么事情,于是LZ就研究了一下几种语言的皮毛,在这里献丑一翻,希望各位猿友莫要见笑. 不过说来也 ...
- 小冷-wireshark的标志位的值是啥
小冷系列之 wireshark的标志位的值是啥,在用wireshark抓包时,发现Flags = 0x002(SYN),很好奇0x002是什么意思. 好不好先上图: 上图是一个三次握手第一次的标志位, ...
- java事物详解
一.什么是Java事务 通常的观念认为,事务仅与数据库相关. 事务必须服从ISO/IEC所制定的ACID原则.ACID是原子性(atomicity).一致性(consistency).隔离性 (iso ...
- Yii2 创建新项目目录
默认的高级应用模板包括三个应用 backend – 应用的后台 frontend – 应用的前台 console – 应用的控制台应用 那么如果我们要在增加应用呢?比如在加一个手机端的应用,或者后台和 ...
- ipcs命令详解
基础命令学习目录首页 多进程间通信常用的技术手段包括共享内存.消息队列.信号量等等,Linux系统下自带的ipcs命令是一个极好的工具,可以帮助我们查看当前系统下以上三项的使用情况,从而利于定位多进程 ...
- react-native 常规操作
1. 关闭xcode打开模拟器的快捷键 , 等常规操作 https://www.jianshu.com/p/f6723f3406b7
- babel无法编译?
ECMAScript 6(ES6)的发展或者说普及之快可以说是难以想象的,对很多人来说ECMAScript 5(ES5)都还普及呢.现代浏览器对ES6新特新或多或少的有些支持,但支持度不高,所以要想在 ...
- 2018年第九届蓝桥杯【C++省赛B组】
2标题:明码 汉字的字形存在于字库中,即便在今天,16点阵的字库也仍然使用广泛.16点阵的字库把每个汉字看成是16x16个像素信息.并把这些信息记录在字节中. 一个字节可以存储8位信息,用32个字节就 ...
- Scrum立会报告+燃尽图(Final阶段第五次)
此作业要求参见:https://edu.cnblogs.com/campus/nenu/2018fall/homework/2484 项目地址:https://coding.net/u/wuyy694 ...