首页 > 代码库 > Young Maids

Young Maids

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.
  • 2≤N≤2×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

43 2 4 1

 

 

Sample Output 1

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

21 2

 

 

Sample Output 2

1 2

 


 

Sample Input 3

84 6 3 2 8 5 7 1

 

 

Sample Output 3

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)

 

 

 

//题意:给出一个 p 序列,一个 q 序列,p 中有 1 -- n 的某种排列,q初始为空,现要求可以每次选两个相邻的数,移动到 q 中,要操作到 p 为空,并且要求 q 序列字典序最小

 

题解:相当难想到的一个题,假如有一个区间 l,r,肯定是,选择这区间内与 l 奇偶相同的,并且最小的作为开头,这样才能保证字典序最小,然后第二个数,应该为选的数右边的,并且与 l 奇偶性不同的,作为第二个,也是为了字典序最小,这部分是标准RMQ问题,随便用什么。然后,区间被分割成最多三块,用优先队列保存区间即可,n*lgn

还是难以想到啊,很好的题

技术分享
  1 # include <cstdio>  2 # include <cstring>  3 # include <cstdlib>  4 # include <iostream>  5 # include <vector>  6 # include <queue>  7 # include <stack>  8 # include <map>  9 # include <set> 10 # include <cmath> 11 # include <algorithm> 12 using namespace std; 13 # define lowbit(x) ((x)&(-x)) 14 # define pi acos(-1.0) 15 # define LL long long 16   17 # define eps 1e-8 18 # define MOD 1000000007 19 # define INF 0x3f3f3f3f 20 inline int Scan() { 21     int x=0,f=1; char ch=getchar(); 22     while(ch<0||ch>9){if(ch==-) f=-1; ch=getchar();} 23     while(ch>=0&&ch<=9){x=x*10+ch-0; ch=getchar();} 24     return x*f; 25 } 26 inline void Out(int a) { 27     if(a<0) {putchar(-); a=-a;} 28     if(a>=10) Out(a/10); 29     putchar(a%10+0); 30 } 31 const int MX=200005; 32 //Code begin.... 33   34 int n; 35 int dat[MX]; 36 int ans[MX]; 37 int mn[MX]; 38 int st[2][MX][40]; 39 struct Qu 40 { 41     int l,r; 42     int dex; //zui xiao ,,biao hao 43     bool operator < (const Qu b) const{ 44         return dat[dex]>dat[b.dex]; 45     } 46 }; 47 void Init() 48 { 49     mn[0]=-1; 50     dat[0]=INF; 51     for (int i=1;i<=n;i++) 52     { 53         if ((i&(i-1))==0) mn[i]=mn[i-1]+1; 54         else mn[i]=mn[i-1]; 55   56         if (i&1) st[1][i][0]=i; 57         else st[0][i][0]=i; 58     } 59   60     for (int j=1;(1<<j)<=n;j++) 61     { 62         for (int i=1;(i+(1<<j)-1)<=n;i++) 63         { 64             if (dat[st[0][i][j-1]]<=dat[st[0][i+(1<<(j-1))][j-1]]) 65                 st[0][i][j] = st[0][i][j-1]; 66             else 67                 st[0][i][j] = st[0][i+(1<<(j-1))][j-1]; 68   69             if (dat[st[1][i][j-1]]<=dat[st[1][i+(1<<(j-1))][j-1]]) 70                 st[1][i][j] = st[1][i][j-1]; 71             else 72                 st[1][i][j] = st[1][i+(1<<(j-1))][j-1]; 73         } 74     } 75 } 76 int st_cal(int l,int r,int same) 77 { 78     int k = mn[r-l+1]; 79     int c; 80     if (same) c=l%2; 81     else c=(l+1)%2; 82   83     if (dat[st[c][l][k]]<=dat[st[c][r-(1<<k)+1][k]]) 84         return st[c][l][k]; 85     else 86         return st[c][r-(1<<k)+1][k]; 87 } 88   89 int main() 90 { 91     scanf("%d",&n); 92     for (int i=1;i<=n;i++) 93         dat[i] = Scan(); 94     Init(); 95     priority_queue<Qu> Q; 96     Q.push((Qu){1,n,st_cal(1,n,1)}); 97     int pp=0; 98     for (int i=1;i<=n/2;i++) 99     {100         Qu now = Q.top();Q.pop();101         int ml = now.dex;102         int mr = st_cal(ml+1,now.r,1);103         ans[pp++]=dat[ml];104         ans[pp++]=dat[mr];105         if (ml>now.l)106             Q.push( (Qu){now.l,ml-1,st_cal(now.l,ml-1,1)}  );107         if (mr-1>ml)108             Q.push( (Qu){ml+1,mr-1,st_cal(ml+1,mr-1,1)}  );109         if (mr<now.r)110             Q.push( (Qu){mr+1,now.r,st_cal(mr+1,now.r,1)}  );111     }112     for (int i=0;i<pp-1;i++)113         printf("%d ",ans[i]);114     printf("%d\n",ans[pp-1]);115     return 0;116 }
View Code

 

Young Maids