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);
}
}