AtCoder Regular Contest 080 E

来源:互联网 发布:非交互式的域名备案 编辑:程序博客网 时间:2024/06/07 03:19

E - Young Maids


Time limit : 2sec / Memory limit : 256MB

Score : 800 points

Problem Statement

Let N be a positive even number.

We have a permutation of (1,2,…,N)p=(p1,p2,…,pN). Snuke is constructing another permutation of (1,2,…,N)q, following the procedure below.

First, let q be an empty sequence. Then, perform the following operation until p becomes empty:

  • Select two adjacent elements in p, and call them x and y in order. Remove x and y from p (reducing the length of p by 2), and insert x and y, preserving the original order, at the beginning of q.

When p becomes empty, q will be a permutation of (1,2,…,N).

Find the lexicographically smallest permutation that can be obtained as q.

Constraints

  • N is an even number.
  • 2N2×105
  • p is a permutation of (1,2,…,N).

Input

Input is given from Standard Input in the following format:

Np1 p2  pN

Output

Print the lexicographically smallest permutation, with spaces in between.


Sample Input 1

Copy
43 2 4 1

Sample Output 1

Copy
3 1 2 4

The solution above is obtained as follows:

pq(3,2,4,1)()↓↓(3,1)(2,4)↓↓()(3,1,2,4)

Sample Input 2

Copy
21 2

Sample Output 2

Copy
1 2

Sample Input 3

Copy
84 6 3 2 8 5 7 1

Sample Output 3

Copy
3 1 2 7 4 6 8 5

The solution above is obtained as follows:

pq(4,6,3,2,8,5,7,1)()↓↓(4,6,3,2,7,1)(8,5)↓↓(3,2,7,1)(4,6,8,5)↓↓(3,1)(2,7,4,6,8,5)↓↓()(3,1,2,7,4,6,8,5)


#include <iostream>#include <bits/stdc++.h>using namespace std;typedef long long LL;const int N = 2e6+10;int a[N],  pos[N], sum1[N<<2], sum2[N<<2], n,  ans;// 1 奇数 , 2 偶数typedef pair<int,int> pi;struct node{    int first,second,l,r;    bool operator <(const node &A)const    {        return A.first<first;    }};vector<node>p;void build(int l,int r,int rt){    if(l==r)    {        scanf("%d", &a[l]);        if(l&1)   sum1[rt]=a[l],sum2[rt]=0x3f3f3f3f;        else sum1[rt]=0x3f3f3f3f,sum2[rt]=a[l];        pos[a[l]]=l;        return ;    }    int mid=(l+r)/2;    build(l,mid,rt*2);    build(mid+1,r,rt*2+1);    sum1[rt]=min(sum1[rt<<1],sum1[rt<<1|1]);    sum2[rt]=min(sum2[rt<<1],sum2[rt<<1|1]);    return ;}int query1(int l,int r,int rt,int L,int R){    if(L<=l&&R>=r)  return sum1[rt];    int mid=(l+r)/2;    int ans=0x3f3f3f3f;    if(L<=mid) ans=min(ans,query1(l,mid,rt*2,L,R));    if(R>mid) ans=min(ans,query1(mid+1,r,rt*2+1,L,R));    return ans;}int query2(int l,int r,int rt,int L,int R){    if(L<=l&&R>=r)  return sum2[rt];    int mid=(l+r)/2;    int ans=N+1;    if(L<=mid) ans=min(ans,query2(l,mid,rt*2,L,R));    if(R>mid) ans=min(ans,query2(mid+1,r,rt*2+1,L,R));    return ans;}priority_queue<node>q;int main(){    scanf("%d", &n);    build(1,n,1);    int x=query1(1,n,1,1,n);    int y=query2(1,n,1,pos[x]+1,n);    q.push((node){x,y,1,n});    for(int i=1;i<=n/2;i++)    {        node tmp=q.top();q.pop();        p.push_back(node{tmp.first,tmp.second,0,0});        int al=pos[tmp.first], ar=pos[tmp.second];        if(tmp.l<al-1)        {            if(tmp.l&1)            {                x=query1(1,n,1,tmp.l,al-1);                y=query2(1,n,1,pos[x]+1,al-1);            }            else            {                x=query2(1,n,1,tmp.l,al-1);                y=query1(1,n,1,pos[x]+1,al-1);            }            q.push(node{x,y,tmp.l,al-1});        }        if(al<ar-1)        {            if((al+1)&1)            {                x=query1(1,n,1,al+1,ar-1);                y=query2(1,n,1,pos[x]+1,ar-1);            }            else            {                x=query2(1,n,1,al+1,ar-1);                y=query1(1,n,1,pos[x]+1,ar-1);            }            q.push(node{x,y,al+1,ar-1});        }        if(ar<tmp.r-1)        {            if((ar+1)&1)            {                x=query1(1,n,1,ar+1,tmp.r);                y=query2(1,n,1,pos[x]+1,tmp.r);            }            else            {                x=query2(1,n,1,ar+1,tmp.r);                y=query1(1,n,1,pos[x]+1,tmp.r);            }            q.push(node{x,y,ar+1,tmp.r});        }    }    for(int i=0; i<p.size(); i++)    {        if(i==p.size()-1)printf("%d %d\n",p[i].first,p[i].second);        else printf("%d %d ",p[i].first,p[i].second);    }    return 0;}










原创粉丝点击