ARC080E
倒着考虑
每次拿出的第一个必须是奇数位置,第二个必须是偶数位置。每次删数都不能跨过已被删去的位置。
事实上只要开个堆维护一下区间就行了。但是众所周知我zz,所以我写的线段树
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int M = 1000001;
int n,m,k,a[M],d[2][M],mr[M],tag[M],R[M],w[2][M];
void update(int now)
{
if(d[0][now*2]>d[0][now*2+1])
{
d[0][now]=d[0][now*2+1];
w[0][now]=w[0][now*2+1];
}
else
{
d[0][now]=d[0][now*2];
w[0][now]=w[0][now*2];
}
if(d[1][now*2]>d[1][now*2+1])
{
d[1][now]=d[1][now*2+1];
w[1][now]=w[1][now*2+1];
}
else
{
d[1][now]=d[1][now*2];
w[1][now]=w[1][now*2];
}
}
void built(int now,int l,int r)
{
if(l==r)
{
int t=l&1;
d[!t][now]=0x3f3f3f3f;
d[t][now]=a[l];
w[t][now]=l;
mr[now]=n;
return ;
}
int mid=(l+r)>>1,t=0;
built(now*2,l,mid); built(now*2+1,mid+1,r);
update(now);
mr[now]=n;
}
void pd(int now)
{
if(tag[now])
{
swap(d[0][now*2],d[1][now*2]);
swap(d[0][now*2+1],d[1][now*2+1]);
swap(w[0][now*2],w[1][now*2]);
swap(w[0][now*2+1],w[1][now*2+1]);
tag[now*2]^=1; tag[now*2+1]^=1;
tag[now]=0;
}
mr[now*2]=min(mr[now*2],mr[now]);
mr[now*2+1]=min(mr[now*2+1],mr[now]);
}
int ask1(int now,int l,int r)
{
if(l==r) {R[l]=mr[now]; d[1][now]=0x3f3f3f3f; return l;}
int mid=(l+r)>>1,k; pd(now);
if(d[1][now]==d[1][now*2]) k=ask1(now*2,l,mid);
else k=ask1(now*2+1,mid+1,r);
update(now);
return k;
}
int ask2(int now,int l,int r,int L,int R)
{
if(l>=L && r<=R) return w[0][now];
int mid=(l+r)>>1,g,k=0; pd(now);
if(L<=mid) k=ask2(now*2,l,mid,L,R);
if(R>mid)
{
g=ask2(now*2+1,mid+1,r,L,R);
if(a[g]<a[k]) k=g;
}
return k;
}
void mody2(int now,int l,int r,int L,int R,int x)
{
if(l>=L && r<=R)
{
if(x)
{
tag[now]^=1;
swap(d[0][now],d[1][now]);
swap(w[0][now],w[1][now]);
}
mr[now]=min(mr[now],R);
return ;
}
int mid=(l+r)>>1; pd(now);
if(L<=mid) mody2(now*2,l,mid,L,R,x);
if(R>mid) mody2(now*2+1,mid+1,r,L,R,x);
update(now);
}
void mody1(int now,int l,int r,int x)
{
if(l==r)
{
d[0][now]=0x3f3f3f3f;
w[0][now]=0;
return ;
}
int mid=(l+r)>>1; pd(now);
if(x<=mid) mody1(now*2,l,mid,x);
else mody1(now*2+1,mid+1,r,x);
update(now);
}
int main()
{
scanf("%d",&n); a[0]=0x3f3f3f3f;
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
built(1,1,n);
for(int i=1;i<=n/2;i++)
{
int k=ask1(1,1,n);
printf("%d ",a[k]);
int g=ask2(1,1,n,k+1,R[k]);
printf("%d ",a[g]);
mody1(1,1,n,g);
if(g-k>1)mody2(1,1,n,k+1,g-1,1);
if(k!=1)mody2(1,1,n,1,k-1,0);
}
}
ARC080E的更多相关文章
- Atcoder arc080E Young Maids(线段树+优先队列)
给出一个n排列,每次可以选择相邻的两个数字放在新的排列首部,问最后形成的新的排列字典序最小是? 考虑新排列的第一个数字,则应是下标为奇数的最小数,下标不妨设为i.第二个数字应该下标大于i且为偶数的最小 ...
- 在$CF$水题の记录
CF1158C CF1163E update after CF1173 很好,我!expert!掉rating了!! 成为pupil指日可待== 下次要记得合理安排时间== ps.一道题都没写的\(a ...
随机推荐
- #1062 - Duplicate entry '1' for key 'PRIMARY'
insert into db1.table_name_xxx select * from db2.table_name_xxx 从一张表导入到另一张表时出错. 默认是两张字段结构相同的情况 原因: 1 ...
- python内存管理及垃圾回收
一.python的内存管理 python内部将所有类型分成两种,一种由单个元素组成,一种由多个元素组成.利用不同结构体进行区分 /* Nothing is actually declared to b ...
- Python里面search()和match()的区别?
match()函数只检测RE是不是在string的开始位置匹配,search()会扫描整个string查找匹配, 也就是说match()只有在0位置匹配成功的话才有返回,如果不是开始位置匹配成功的话, ...
- 哪些文件在vue项目中很重要,哪些可以删掉
是时候告诉你重要文件是哪些了,这是一个陆游,所以 需要路由配置 index.js 路由配置文件是index.js注意这个文件最开始就在集成路由了 然后最开始集成路由的地方可以不写后缀名字,因此注意这个 ...
- 浮点字符串转int类型报错,解决
一,直接上代码,先转double,再强转int,看你是选择,舍入,还是直接取整数位 var a1 = "1500.76"; var a2 = Convert.ToDouble(a1 ...
- js 屏蔽网页快捷键代码
<script> function KeyDown(){ //屏蔽鼠标右键.Ctrl+n.shift+F10.F5刷新.退格键 //alert("ASCII代码是:"+ ...
- elasticsearch Java Client用户指南
这里使用的Java客户端版本是5.1.2,Elasticsearch的版本号也要是5.1.2,否则一些功能可能不支持. 之前介绍过Spring Data Elasticsearch,那里也是使用了本文 ...
- DVR和NVR的区别(深度好文)(转)
DVR接模拟摄像机,NVR是接IP camera的录像机. DVR的录像效果取决于摄像机与DVR本身的压缩算法与芯片处理能力,而NVR的录像效果则主要取决于IPcamera,因为IPcamera输出的 ...
- 带你逐行阅读redux源码
带你逐行阅读redux源码 redux版本:2019-7-17最新版:v4.0.4 git 地址:https://github.com/reduxjs/redux/tree/v4.0.4 redux目 ...
- jquery submit事件
jquery submit 事件 $('#form').submit(function(){ if(true){ //do return true; }else{ //do return false; ...