倒着考虑

每次拿出的第一个必须是奇数位置,第二个必须是偶数位置。每次删数都不能跨过已被删去的位置。

事实上只要开个堆维护一下区间就行了。但是众所周知我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的更多相关文章

  1. Atcoder arc080E Young Maids(线段树+优先队列)

    给出一个n排列,每次可以选择相邻的两个数字放在新的排列首部,问最后形成的新的排列字典序最小是? 考虑新排列的第一个数字,则应是下标为奇数的最小数,下标不妨设为i.第二个数字应该下标大于i且为偶数的最小 ...

  2. 在$CF$水题の记录

    CF1158C CF1163E update after CF1173 很好,我!expert!掉rating了!! 成为pupil指日可待== 下次要记得合理安排时间== ps.一道题都没写的\(a ...

随机推荐

  1. 【Mock.js】前端模拟假数据,不用在手拼了

    [Mock.js]前端模拟假数据,不用在手拼了:https://www.jianshu.com/p/8579b703a4c1

  2. luoguP1083 借教室(题解)(我用的线段树)

    luoguP1083 借教室 题目 #include<cstdio> #include<iostream> #include<cmath> #include< ...

  3. CSS3 3D旋转下拉菜单--兼容性不太好

    <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...

  4. 51-python基础-python3-列表-常用列表方法- index()方法

    index()方法 1-可以传入一个值,如果该值存在于列表中,就返回它的下标. 实例1: 2-如果该值不在列表中,Python 就报 ValueError. 实例2: 3-如果列表中存在重复的值,就返 ...

  5. go读写excel文件

    首先,需要安装golang用来操作excel文档的类库: go get github.com/Luxurioust/excelize 一.excel文件创建与写入 package main impor ...

  6. mySQL查看存储过程、函数、视图、触发器

    一.查看存储过程 1.show procedure status; //查看所有的 2.show create procedure proc_AllUser[proc_name]; 查看proc_Al ...

  7. 最长上升子序列(LIS)长度及其数量

    例题51Nod-1376,一个经典问题,给出一个序列问该序列的LIS以及LIS的数量. 这里我学习了两种解法,思路和代码都是参考这两位大佬的: https://www.cnblogs.com/reve ...

  8. tomcat如何正确的开启远程调试功能(转)

    转自:http://blog.csdn.net/mhmyqn/article/details/49209541 版权声明:本文为博主原创文章,未经博主允许不得转载. 在日常开发中,有时需要对远程服务器 ...

  9. oracle 的使用

    一. docker 模式下进入数据库 ubuntu@jiang:~$ sudo docker ps -a sudo: unable to resolve host jiang CONTAINER ID ...

  10. python3 利用configparser生成和读取配置文件

    利用configparser生成和读取配置文件 #Author by Andy #_*_ coding:utf-8 _*_ import configparser ''' 配置文件格式 groupna ...