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存储蚂蚁前 ...
随机推荐
- vs2015新功能和其他
1.自2011版本开始开发式编译器发布:Roslyn,其提供的API可以侦测dll编译过程中访问和分析编译数据,传统的编译器都是黑盒子:源代码从黑盒子的一端进入,目标文件/程序集从另一端出来. 2.最 ...
- c# table 怎么在前台循环展示 ViewBag
后台 public ActionResult DoctorEvaluation()//前台页面 { HE_Department HE_dt = new HE_Department(); DataTab ...
- sqlmap注入分类
注入分法不同,种类不同,来个简单的分类: 1.get型:sqlmap -u “http://xxx.xx.xxx/xx.xxx?xx=xxx” 2.post型: sqlmap -u “http:// ...
- fiddler对安卓APP进行抓包
操作流程: 1.fiddler导出ca证书 操作路径: Tools -> Fiddler Options -> HTTPS -> Export Fiddler Root Certif ...
- 曾经的华为C面试题,一点就通
学习编程可以锻炼你的思维,帮助你更好地思考,创建一种我认为在各领域都非常有用的思维方式. 比尔盖茨 曾经的华为C面试题,一点就通 [问题区] 有两个变量x和y, x=10; y = 2 ...
- 【CentOS 7】nginx配置web服务器
1,安装过程 [root@VM_1_14_centos ~]# cd /data/ [root@VM_1_14_centos data]# wget http://nginx.org/download ...
- java后端面试题汇总
转载链接:https://www.nowcoder.com/discuss/90776?type=0&order=0&pos=23&page=0 基础篇 数据结构与算法 线性表 ...
- tensorflow enqueue_many传入多个值的列表传入异常问题————Shape () must have rank at least 1
tf 的队列操作enqueue_many传入的值是列表,但是放入[]列表抛异常 File "C:\Users\lihongjie\AppData\Local\Programs\Python\ ...
- 互评Beta版本——杨老师粉丝群——Pinball
互评beta版本 杨老师粉丝群——<PinBall> 一.基于NABCD评论作品,及改进建议 1.根据(不限于)NABCD评论作品的选题 (1)N(Need,需求) 随着年龄的增长, ...
- 感谢Thunder团队
不知不觉中,团队开发的beta版本都已经结束.开发的路上我们一起解决了很多难题,相互帮助走到了现在. 首先我想感谢组长王航.认真负责合理分配任务,使得我们每次发布都可以顺利并且按时完成.感谢胡佑蓉,李 ...