【算法】数学+堆

【题意】给定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. Objective-C反射机制

    oc反射机制有三个用途: 1.获得Class Class LoginViewController = NSClassFromString(@"LoginViewController" ...

  2. OpenCV入门:(五:更改图片对比度和亮度)

    1. 理论 图片的转换就是将图片中的每个像素点经过一定的变换,得到新像素点,新像素点组合成一张新的图片. 改变图片对比度和亮度的变换如下: 其中α和β被称作增益参数(gain parameter)和偏 ...

  3. Sql面试题之三(难度:简单| 含答案)

    Sql面试题之三(难度:简单| 含答案) 答案: .SELECT B.name, B.Depart T.Content FROM B, T WHERE ( T.Content = '税法培训' and ...

  4. Python 基本文件操作

    文件模式 'r' 读模式 'w' 写模式 (清除掉旧有数据并重新开始) 'a' 追加模式 'b' 二进制模式 '+' 读/写模式 注意: 'b'   : 二进制模式 可添加到其他模式中使用 '+'  ...

  5. git 创建分支并提交到服务器对应的新分支

    1.切换到源分支 git checkout test 2.在源分支的基础上创建新分支 git branch test1 3.提交到远程分支 git pull 会自动提示下面的命令 git pull - ...

  6. HDU 4582 DFS spanning tree(DFS+贪心)(2013ACM-ICPC杭州赛区全国邀请赛)

    Problem Description Consider a Depth-First-Search(DFS) spanning tree T of a undirected connected gra ...

  7. python 注册表重置ie代理 ss使用后的代理恢复

    每次用完ss客户端,浏览器代理都不会改回来,不想手动改,只能用python脚本处理了. import winreg def disableProxy(): proxy = "" x ...

  8. win7 C/C++,QT安装环境总结

    1. 安装VMware,但是不能用,发现是权限问题,解决方式:使用管理员运行模式即可: 2. 安装win7 ultimate x64,找了半天找不到密钥,只要用激活软件,目前来说系统可用 3. 安装 ...

  9. [剑指Offer] 19.顺时针打印矩阵

    [思路]本题关键在于 右->左 和 下->上 两个循环体中的判断条件,即判断是否重复打印. class Solution { public: vector<int> print ...

  10. mac --snip 滚动截屏

    1.snip 下载配置:https://jingyan.baidu.com/article/fec4bce2458d03f2618d8b8e.html 2.mac的火狐浏览器好像不支持,必须在sofa ...