P3165 [CQOI2014]排序机械臂

P3165 [CQOI2014]排序机械臂

题目描述

为了把工厂中高低不等的物品按从低到高排好序,工程师发明了一种排序机械臂。它遵循一个简单的排序规则,第一次操作找到摄低的物品的位置P1,并把左起第一个至P1间的物品反序;第二次找到第二低的物品的位置P2,并把左起第二个至P2间的物品反序...最终所有的物品都会被排好序。

上图给出_个示例,第_次操作前,菝低的物品在位置4,于是把第1至4的物品反序;第二次操作前,第二低的物品在位罝6,于是把第2至6的物品反序...

你的任务便是编写一个程序,确定一个操作序列,即每次操作前第i低的物品所在位置Pi,以便机械臂工作。需要注意的是,如果有高度相同的物品,必须保证排序后它们的相对位置关系与初始时相同。

输入输出格式

输入格式:

 

第一行包含正整数n,表示需要排序的物品数星。

第二行包含n个空格分隔的整数ai,表示每个物品的高度。

 

输出格式:

 

输出一行包含n个空格分隔的整数Pi。

 

输入输出样例

输入样例#1: 复制
6
3 4 5 1 6 2
输出样例#1: 复制
4 6 4 5 6 6

 

 

code

神奇的splay

 

  1 #include<cstdio>
  2 #include<algorithm>
  3 
  4 using namespace std;
  5 
  6 const int N = 500100;
  7 const int INF = 1e9;
  8 
  9 int data[N],siz[N],mn[N],pos[N],tag[N],ch[N][2],fa[N],st[N];
 10 int Root,top;
 11 
 12 struct Data{
 13     int x,p;
 14 }d[N];
 15 
 16 inline char nc() {
 17     static char buf[100000],*p1 = buf,*p2 = buf;
 18     return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2) ? EOF : *p1++;
 19 }
 20 inline int read() {
 21     int x = 0,f = 1;char ch = nc();
 22     for (; ch<'0'||ch>'9'; ch = nc())
 23         if (ch=='-') f = -1;
 24     for (; ch>='0'&&ch<='9'; ch = nc())
 25         x = x * 10 + ch - '0';
 26     return x * f;
 27 }
 28 bool cmp1(Data a,Data b) {
 29     if (a.x==b.x) return a.p < b.p;
 30     return a.x < b.x;
 31 }
 32 bool cmp2(Data a,Data b) {
 33     return a.p < b.p;
 34 }
 35 inline void pushup(int x) {
 36     int l = ch[x][0],r = ch[x][1];
 37     mn[x] = data[x],pos[x] = x;
 38     if (mn[l] < mn[x]) mn[x] = mn[l],pos[x] = pos[l];
 39     if (mn[r] < mn[x]) mn[x] = mn[r],pos[x] = pos[r];//-
 40     siz[x] = siz[l] + siz[r] + 1;
 41 }
 42 inline void pushdown(int x) {
 43     if (tag[x]) {
 44         tag[ch[x][0]] ^= 1;
 45         tag[ch[x][1]] ^= 1;
 46         swap(ch[x][0],ch[x][1]);
 47         tag[x] ^= 1;
 48     }
 49 }
 50 inline int son(int x) {
 51     return x == ch[fa[x]][1]; //-
 52 }
 53 inline void rotate(int x) {
 54     int y = fa[x],z = fa[y],b = son(x),c = son(y),a = ch[x][!b];
 55     if (z) ch[z][c] = x;else Root = x;fa[x] = z; //-
 56     ch[x][!b] = y;fa[y] = x;
 57     ch[y][b] = a;if (a) fa[a] = y;
 58     pushup(y);pushup(x);
 59 }
 60 inline void splay(int x,int rt) {
 61     top = 0;int p = x;//--
 62     while (p) st[++top] = p,p = fa[p];
 63     while (top) pushdown(st[top]),top--;
 64     while (fa[x] != rt) {
 65         int y = fa[x],z = fa[y];
 66         if (z==rt) rotate(x);
 67         else {
 68             if (son(x)==son(y)) rotate(y),rotate(x);
 69             else rotate(x),rotate(x);
 70         }
 71     }
 72 }
 73 inline int getkth(int k) {
 74     int p = Root;
 75     while (true) {
 76         pushdown(p);
 77         if (k == siz[ch[p][0]] + 1) return p;
 78         if (ch[p][0] && siz[ch[p][0]] >= k) p = ch[p][0];
 79         else {
 80             k -= ((ch[p][0] ? siz[ch[p][0]] : 0) + 1);
 81             p = ch[p][1];
 82         }
 83     }
 84 }
 85 inline int getmnpos(int l,int r) {
 86     int L = getkth(l),R = getkth(r+2);
 87     splay(L,0);
 88     splay(R,L);
 89     return pos[ch[R][0]];
 90 }
 91 inline void rever(int l,int r) {
 92     int L = getkth(l),R = getkth(r+2);
 93     splay(L,0);splay(R,L);
 94     tag[ch[R][0]] ^= 1;
 95 }
 96 int build(int l,int r) {
 97     if (l > r) return 0;
 98     /*if (l==r) {
 99         siz[l] = 1;data[l] = mn[l] = d[l].x;pos[l] = l;
100         return l;
101     }*/
102     int mid = (l + r) >> 1;
103     int t = build(l,mid-1);
104     fa[t] = mid;ch[mid][0] = t;
105     t = build(mid+1,r);
106     fa[t] = mid;ch[mid][1] = t;
107     data[mid] = d[mid].x; //= mn[mid]pos[mid] = mid;
108     pushup(mid);
109     return mid;
110 }
111 
112 int main() {
113     int n = read();
114     d[1].x = d[n+2].x = mn[0] = INF;
115     for (int i=2; i<=n+1; ++i) 
116         d[i].x = read(),d[i].p = i;
117     sort(d+2,d+n+2,cmp1);
118     for (int i=2; i<=n+1; ++i) 
119         d[i].x = i - 1; // 没有相等的 
120     sort(d+2,d+n+2,cmp2);
121     Root = build(1,n+2);
122     for (int i=1; i<=n; ++i) {
123         int x = getmnpos(i,n);
124         splay(x,0);
125         printf("%d ",siz[ch[x][0]]); // siz[ch[x][0]] + 1 - 1
126         rever(i,siz[ch[x][0]]);
127     }
128     return 0;
129 }

 

posted @ 2017-12-09 09:50  MJT12044  阅读(234)  评论(0编辑  收藏  举报