【算法】数学+堆

【题意】给定n个数的排列,每次操作可以取两个数按序排在新序列的头部,求最小字典序。

【题解】

转化为每次找字典序最小的两个数按序排在尾部,则p1和p2的每次选择都必须满足:p1在当前序列的奇数位置,p2在当前序列的偶数位置且位于p1之后。满足条件的情况下每次找最小。

每次找到p1和p2都把序列划分为3部分,递归进行,初步想到使用归并。

进一步考虑性质,每对数字要出现必须它的上属序列的p1和p2必须出现,此外没有其他要求。

所以用优先队列维护每个序列,序列的优先级为p1,每次处理一个序列才能加入其三个子序列。

#include<cstdio>
#include<algorithm>
#include<queue>
#include<cstring>
using namespace std;
const int maxn=,inf=0x3f3f3f3f;
int a[maxn],n,logs[maxn],d[][maxn][],pos[maxn];
struct cyc{
int l,r,x;
bool operator <(const cyc &a)const
{return x>a.x;}
};
priority_queue<cyc>q; void RMQ_INIT(int k){
for(int j=;(<<j)<=n;j++)
for(int i=;i+(<<j)-<=n;i++)
d[k][i][j]=min(d[k][i][j-],d[k][i+(<<(j-))][j-]);
}
int rmq(int l,int r,int k){
int K=logs[r-l+];
return min(d[k][l][K],d[k][r-(<<K)+][K]);
} int main(){
scanf("%d",&n);
for(int i=;i<=n;i++){
scanf("%d",&a[i]);
d[i&][i][]=a[i];//1奇数
d[(i&)^][i][]=inf;//0偶数
pos[a[i]]=i;//因为是排列可以直接记位置,省去RMQ的位置记录。
}
logs[]=-;for(int i=;i<=n;i++)logs[i]=logs[i>>]+;
RMQ_INIT();RMQ_INIT();
q.push((cyc){,n,rmq(,n,)});
int L,R,p1,p2;
while(!q.empty()){
cyc x=q.top();q.pop();
L=x.l;R=x.r;p1=pos[x.x];
p2=pos[rmq(p1+,R,(p1&)^)];
printf("%d %d ",a[p1],a[p2]);
if(L<p1)q.push((cyc){L,p1-,rmq(L,p1-,(L&))});
if(p1<p2-)q.push((cyc){p1+,p2-,rmq(p1+,p2-,(p1+)&)});
if(p2<R)q.push((cyc){p2+,R,rmq(p2+,R,(p2+)&)});
}
return ;
}

【Atcoder】ARC 080 E - Young Maids的更多相关文章

  1. 【Atcoder】ARC 080 F - Prime Flip

    [算法]数论,二分图最大匹配 [题意]有无限张牌,给定n张面朝上的牌的坐标(N<=100),其它牌面朝下,每次操作可以选定一个>=3的素数p,并翻转连续p张牌,求最少操作次数使所有牌向下. ...

  2. 【AtCoder】ARC 081 E - Don't Be a Subsequence

    [题意]给定长度为n(<=2*10^5)的字符串,求最短的字典序最小的非子序列字符串. http://arc081.contest.atcoder.jp/tasks/arc081_c [算法]字 ...

  3. 【AtCoder】 ARC 097

    link C-K-th Substring 题意:找出已知串中第\(k\)大的子串,子串相同的不算 \(k\)好小啊,要怎么做啊 不是[Tjoi2015]弦论吗 算了,直接SAM吧 #include& ...

  4. 【递归】【线段树】【堆】AtCoder Regular Contest 080 E - Young Maids

    给你一个1~n的排列p,n是偶数,每次从中任选一对相邻的数出来,插到排列q的开头,如此循环,问你所能得到的字典序最小的排列q. 我们先确定q开头的两个数q1,q2,q1一定是p的奇数位的最小的数,而q ...

  5. 【AtCoder】 ARC 096

    link C-Half and Half 题意:三种pizza,可以花\(A\)价钱买一个A-pizza,花\(B\)价钱买一个B-pizza,花\(C*2\)价钱买A-pizza和B-pizza各一 ...

  6. 【AtCoder】 ARC 098

    link C-Attention 题意:一个字符队列,每个位置是\(W\)或\(E\),计算最小的修改数量,使得存在一个位置,它之前的都是\(E\),之后的都是\(F\) #include<bi ...

  7. 【AtCoder】 ARC 099

    link C-Minimization 枚举覆盖\(1\)的区间,两边的次数直接算 #include<bits/stdc++.h> #define ll long long #define ...

  8. 【AtCoder】 ARC 100

    link C-Linear Approximation 给出\(N\)个数\(A_1,A_2,...,A_N\) ,求一个数\(d\),最小化\(\sum_{i=1}^N|A_i-(d+i)|\) 把 ...

  9. 【AtCoder】 ARC 101

    link 搬来了曾经的题解 C-Candles 题意:数轴上有一些点,从原点开始移动到达这些点中的任意\(K\)个所需要的最短总路程 \(K\)个点必然是一个区间,枚举最左边的就行了 #include ...

随机推荐

  1. leetcode笔记--3 Niim game

    question: You are playing the following Nim Game with your friend: There is a heap of stones on the ...

  2. GDB抓虫之旅(上篇)

    本文来自网易云社区. 作者:盛国存 前言 问: gdb是什么? 答: 强大的UNIX下命令行调试工具. 问: gdb能干什么? 答: 让你随心所欲的驾驭你的程序:Start.Stop.Examine. ...

  3. 一个极为简单的requirejs实现

    require和 sea的源码分析,我之前的博客有写过, 今天我想分享的是一个很简单的核心代码(不带注释和空行大概60行), 没有容错判断. require.js require函数实现用一句话概括: ...

  4. iOS URL加解密

    URL加解密 背景介绍 iOS 下URL加解密,项目使用AFNetworking 虽然是使用HTTPS,但是从安全方面考虑,在很多情况下还是需要对url的参数进行加密的. 接口如 https://19 ...

  5. MySQL☞Group By

    分组: group by 列名:根据某一列,把数据分成几组,经常对每一组的数据使用聚合函数,按照我的理解,该列有几种不同的值,那么就把该列分成几组,如下图 简单的来说,第二列中有两个不同的值a和b,那 ...

  6. Java并发基础--线程安全

    一.线程安全 1.线程安全的概念 线程安全:某个类被单个线程,或者多个线程同时访问,所表现出来的行为是一致,则可以说这个类是线程安全的. 2.什么情况下会出现线程安全问题 在单线程中不会出现线程安全问 ...

  7. P5056 插头dp

    题面 Source: unordered_map: #include <iostream> #include <tr1/unordered_map> #include < ...

  8. not1,not2,bind1st,bind2nd

    例子需要包含头文件 #include <vector> #include <algorithm> #include <functional> bind1st和bin ...

  9. POJ3984(迷宫问题)

    定义一个二维数组: int maze[5][5] = { 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, ...

  10. Flink之状态之checkpointing

    1.前言 在Flink中,函数和操作符都可以是有状态的.在处理每个消息或者元素时,有状态的函数都会储存信息,使得状态成为精密操作中关键的组成部分. 为了使状态能够容错,Flink会checkpoint ...