[BZOJ3506] [Cqoi2014] 排序机械臂 (splay)

Description

  同OJ1552

Input 

Output

Sample Input

Sample Output

HINT

Source

Solution

  Q:哎不是同一道题吗为什么分两篇博客来写?

  A:当然是来骗浏览量了233333333,这里还是会放代码的,当然你左转BZOJ1552的题解也行。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 struct spaly
 4 {
 5     int c[2], fa, siz, rev;
 6 }a[100005];
 7 pair<int, int> b[100005];
 8  
 9 void push_up(int k)
10 {
11     a[k].siz = a[a[k].c[0]].siz + a[a[k].c[1]].siz + 1;
12 }
13  
14 void push_down(int k)
15 {
16     if(a[k].rev)
17     {
18         swap(a[k].c[0], a[k].c[1]), a[k].rev = 0;
19         a[a[k].c[0]].rev ^= 1, a[a[k].c[1]].rev ^= 1;
20     }
21 }
22  
23 void rotate(int &k, int x)
24 {
25     int y = a[x].fa, z = a[y].fa;
26     int dy = a[y].c[1] == x, dz = a[z].c[1] == y;
27     if(k == y) k = x, a[x].fa = z;
28     else a[z].c[dz] = x, a[x].fa = z;
29     a[y].c[dy] = a[x].c[!dy], a[a[x].c[!dy]].fa = y;
30     a[x].c[!dy] = y, a[y].fa = x;
31     push_up(y);
32 }
33  
34 void splay(int &k, int x)
35 {
36     while(k != x)
37     {
38         int y = a[x].fa, z = a[y].fa;
39         push_down(z), push_down(y), push_down(x);
40         if(k != y)
41             if(a[y].c[1] == x ^ a[z].c[1] == y) rotate(k, x);
42             else rotate(k, y);
43         rotate(k, x);
44     }
45     push_up(x);
46 }
47  
48 int find(int k, int x)
49 {
50     if(!k) return 0;
51     push_down(k);
52     if(x <= a[a[k].c[0]].siz) return find(a[k].c[0], x);
53     if(x == a[a[k].c[0]].siz + 1) return k;
54     return find(a[k].c[1], x - a[a[k].c[0]].siz - 1);
55 }
56  
57 int main()
58 {
59     int n, root, pos;
60     while(~scanf("%d", &n) && n)
61     {
62         for(int i = 1; i <= n; i++)
63         {
64             scanf("%d", &b[i].first);
65             b[i].second = i + 1;
66         }
67         sort(b + 1, b + n + 1);
68         for(int i = 1; i <= n + 2; i++)
69         {
70             a[i].fa = i + 1, a[i].c[0] = i - 1;
71             a[i].siz = i, a[i].c[1] = a[i].rev = 0;
72         }
73         a[n + 2].fa = 0, root = n + 2;
74         for(int i = 1; i <= n; i++)
75         {
76             splay(root, b[i].second);
77             pos = a[a[root].c[0]].siz;
78             printf("%d", pos);
79             if(i != n) printf(" ");
80             splay(root, find(root, i));
81             splay(a[root].c[1], find(root, pos + 2));
82             a[a[a[root].c[1]].c[0]].rev ^= 1;
83         }
84         puts("");
85     }
86     return 0;
87 }
View Code
posted @ 2016-04-21 09:45  CtrlCV  阅读(167)  评论(0编辑  收藏  举报