【Atcoder】ARC 080 E - Young Maids
【算法】数学+堆
【题意】给定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的更多相关文章
- 【Atcoder】ARC 080 F - Prime Flip
[算法]数论,二分图最大匹配 [题意]有无限张牌,给定n张面朝上的牌的坐标(N<=100),其它牌面朝下,每次操作可以选定一个>=3的素数p,并翻转连续p张牌,求最少操作次数使所有牌向下. ...
- 【AtCoder】ARC 081 E - Don't Be a Subsequence
[题意]给定长度为n(<=2*10^5)的字符串,求最短的字典序最小的非子序列字符串. http://arc081.contest.atcoder.jp/tasks/arc081_c [算法]字 ...
- 【AtCoder】 ARC 097
link C-K-th Substring 题意:找出已知串中第\(k\)大的子串,子串相同的不算 \(k\)好小啊,要怎么做啊 不是[Tjoi2015]弦论吗 算了,直接SAM吧 #include& ...
- 【递归】【线段树】【堆】AtCoder Regular Contest 080 E - Young Maids
给你一个1~n的排列p,n是偶数,每次从中任选一对相邻的数出来,插到排列q的开头,如此循环,问你所能得到的字典序最小的排列q. 我们先确定q开头的两个数q1,q2,q1一定是p的奇数位的最小的数,而q ...
- 【AtCoder】 ARC 096
link C-Half and Half 题意:三种pizza,可以花\(A\)价钱买一个A-pizza,花\(B\)价钱买一个B-pizza,花\(C*2\)价钱买A-pizza和B-pizza各一 ...
- 【AtCoder】 ARC 098
link C-Attention 题意:一个字符队列,每个位置是\(W\)或\(E\),计算最小的修改数量,使得存在一个位置,它之前的都是\(E\),之后的都是\(F\) #include<bi ...
- 【AtCoder】 ARC 099
link C-Minimization 枚举覆盖\(1\)的区间,两边的次数直接算 #include<bits/stdc++.h> #define ll long long #define ...
- 【AtCoder】 ARC 100
link C-Linear Approximation 给出\(N\)个数\(A_1,A_2,...,A_N\) ,求一个数\(d\),最小化\(\sum_{i=1}^N|A_i-(d+i)|\) 把 ...
- 【AtCoder】 ARC 101
link 搬来了曾经的题解 C-Candles 题意:数轴上有一些点,从原点开始移动到达这些点中的任意\(K\)个所需要的最短总路程 \(K\)个点必然是一个区间,枚举最左边的就行了 #include ...
随机推荐
- PostgreSQL 10.0 压缩版的 pgAdmin 不能用的问题
PostgreSQL终于发布10.0正式版了!下载压缩版的更新了一下本机的版本,然后打开pgAdmin的时候总是报错“The application server could not be conta ...
- Java Web前后端分离的思考与实践
第一节 Java Web开发方式的变化 Web开发虽然是我们常说的B/S模式,其实本质上也是一种特殊的C/S模式,只不过C和S的选择余地相对要窄了不少,而且更标准化.不论是采用什么浏览器和后端框架,W ...
- 用travis-ci编译android版nodejs
第一步: fork 第二步: 添加.travis.yml 在repository根目录添加.travis.yml文件,在其中添加以下内容. language: c before_install: - ...
- fidder工具学习抓取Firefox包
fidder抓取Firefox的https请求 抓包之前需要设置fidder,我下面的截图是fidder4,打开fidder—>Tools—>Options如图: 选择https,勾选所有 ...
- 使用testng.xml组织测试用例
测试用例类TeseNG.java: import org.openqa.selenium.By;import org.openqa.selenium.WebDriver;import org.open ...
- c++知识点总结--函数模板
通用函数可变参模板 用于处理不限定参数的函数 showall(){//空函数,接口,最后结束递归 } template<typename T,typename... Args> void ...
- android4.1 Wifi 浅析
简单分析下wifi相关类,首先了解几个主要概念 AsyncChannel 简单理解: AsyncChannel,就是借助Messenger 机制,让两个不同的handler之间进行通信. AsyncC ...
- 第5讲——cin处理字符输入
本来这一讲应该是while.for.if之类的,但是,我们可是学过C的男人,再浪费时间搞这个??? 还不如学点C++中的新知识. cin对象支持3种不同模式的单字符输入,其用户接口各不相同. 下面我们 ...
- Spring Boot学习(一):入门篇
目录 Spring Boot简介 Spring Boot快速搭建 1 新建项目 2 运行项目 3 设置spring boot可以热部署(修改后端代码后,自动部署,不用手动部署) 3.1:配置pom.x ...
- [剑指Offer] 43.左旋转字符串
题目描述 汇编语言中有一种移位指令叫做循环左移(ROL),现在有个简单的任务,就是用字符串模拟这个指令的运算结果.对于一个给定的字符序列S,请你把其循环左移K位后的序列输出.例如,字符序列S=”abc ...