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 ...
随机推荐
- HDFS文件的基本操作
HDFS文件的基本操作: package wjn; import java.io.BufferedInputStream; import java.io.BufferedReader; import ...
- go语言从例子开始之Example19.接口
接口 是方法特征的命名集合. Example: package main import "fmt" //让方法,实现api这个接口. type api interface{ get ...
- Codeforces 1178F DP
题意:有一张白纸条,你需要给这张纸条染色.染色从颜色1开始染色,每次选择纸条的一段染色时,这一段的颜色必须是相同的.现在给你染色后的纸条,问有多少种染色方案? F1: 思路:最开始的想法是以染色顺序为 ...
- H2数据库做单测数据库时踩到的坑
H2数据库用来做单测数据库,可以自定义初始化数据,不用担心数据库内容更改造成单测跑不过问题,不过H2数据库跟实际使用的Mysql还是有一定区别. 1. H2数据库不支持Mysql的批量更新功能,支持批 ...
- jQuery判断checkbox是否选中的4种方法
方法一: ).checked) { // do something } 方法二: if($('#checkbox-id').is(':checked')) { // do something } 方法 ...
- WGCNA构建基因共表达网络详细教程
这篇文章更多的是对于混乱的中文资源的梳理,并补充了一些没有提到的重要参数,希望大家不会踩坑. 1. 简介 1.1 背景 WGCNA(weighted gene co-expression networ ...
- ICU lirary DownLoad
{ //https://github.com/unicode-org/icu }
- 【纪中集训】2019.08.02【NOIP提高组】模拟 A 组TJ
\(\newcommand{\RNum}[1]{\uppercase\expandafter{\romannumeral #1\relax}}\) T1 一道可以暴力撵标算的题-- Descripti ...
- Mac上的Apache 开启,停止,重启
sudo apachectl -k start 启动 sudo apachectl -k stop 停止 sudo apachectl -k restart 重启
- PHP chdir() 函数
实例 改变当前的目录: <?php// Get current directoryecho getcwd() . "<br>"; // Change direct ...