码迷,mamicode.com
首页 > 其他好文 > 详细

BZOJ1861 [Zjoi2006]Book 书架

时间:2015-05-05 23:32:31      阅读:162      评论:0      收藏:0      [点我收藏+]

标签:

直接模拟过程就好了,维护数列的话用平衡树即可

注意要使用外部指针指向每个数出现的地方,否则没办法直接查找到

 

技术分享
  1 /**************************************************************
  2     Problem: 1861
  3     User: rausen
  4     Language: C++
  5     Result: Accepted
  6     Time:1088 ms
  7     Memory:4004 kb
  8 ****************************************************************/
  9  
 10 #include <cstdio>
 11  
 12 using namespace std;
 13 const int N = 8e4 + 5;
 14  
 15 inline int read();
 16  
 17 namespace treap {
 18     struct node;
 19     node *null, *T, *ptr[N];
 20      
 21     struct node {
 22         node *ls, *rs, *fa;
 23         int v, sz;
 24          
 25         node() {}
 26         node(int _v, node *_f) {
 27             ls = rs = null, fa = _f;
 28             v = _v, sz = 1;
 29         }
 30          
 31         #define Len (1 << 16)
 32         inline void* operator new(size_t, int _v, node *_f) {
 33             static node *mempool, *c;
 34             if (mempool == c)
 35                 mempool = (c = new node[Len]) + Len;
 36             *c = node(_v, _f);
 37             return c++;
 38         }
 39         #undef Len
 40          
 41         inline void update() {
 42             sz = ls -> sz + rs -> sz + 1;
 43             ls -> fa = rs -> fa = this;
 44         }
 45     };
 46      
 47     #define mid (l + r >> 1)
 48     void build(node *&p, node *fa, int l, int r, int *a) {
 49         ptr[a[mid]] = p = new(a[mid], fa)node;
 50         if (l < mid) build(p -> ls, p, l, mid - 1, a);
 51         if (mid < r) build(p -> rs, p ,mid + 1, r, a);
 52         p -> update();
 53     }
 54     #undef mid
 55  
 56      
 57     inline unsigned rand() {
 58         static unsigned res = 826;
 59         return res += res << 2 | 1;
 60     }
 61     inline bool random(int x, int y) {
 62         return rand() % (x + y) < x;
 63     }
 64      
 65     void merge(node *&p, node *x, node *y) {
 66         if (x == null || y == null)
 67             p = x == null ? y : x; else
 68         if (random(x -> sz, y -> sz)) {
 69             p = x;
 70             merge(p -> rs, x -> rs, y);
 71         } else {
 72             p = y;
 73             merge(p -> ls, x, y -> ls);
 74         }
 75         p -> update();
 76     }
 77      
 78     void split(node *p, node *&x, node *&y, int k) {
 79         if (k == 0) {
 80             x = null, y = p;
 81             return;
 82         }
 83         if (k == p -> sz) {
 84             x = p, y = null;
 85             return;
 86         }
 87         if (p -> ls -> sz >= k) {
 88             y = p;
 89             split(p -> ls, x, y -> ls, k);
 90             y -> update();
 91         } else {
 92             x = p;
 93             split(p -> rs, x -> rs, y, k - p -> ls -> sz - 1);
 94             x -> update();
 95         }
 96     }
 97      
 98     inline int get_rank(node *p) {
 99         static int res;
100         res = p -> ls -> sz + 1;
101         while (p != T)
102             res += (p == p -> fa -> rs ? p -> fa -> ls -> sz + 1 : 0), p = p -> fa;
103         return res;
104     }
105      
106     inline void move(int p, int f) {
107         static node *x, *y ,*z;
108         static int t;
109         t = get_rank(ptr[p]);
110         split(T, x, z, t), split(x, x, y, t - 1);
111         if (!f) merge(T, y, x), merge(T, T, z);
112         else merge(T, x, z), merge(T, T, y);
113     }
114      
115     inline void move_to_mid(int d, int p) {
116         if (!d) return;
117         static node *x, *y, *z, *w;
118         static int t;
119         t = get_rank(ptr[p]);
120         split(T, x, z, t), split(x, x, y, t - 1);
121         if (d == -1) {
122             split(x, x, w, t - 2);
123             merge(T, x, y), merge(T, T, w), merge(T, T, z);
124         } else {
125             split(z, w, z, 1);
126             merge(T, x, w), merge(T, T, y), merge(T, T, z);
127         }
128     }
129      
130     inline int kth(node *p, int k) {
131         if (k == p -> ls -> sz + 1) return p -> v;
132         if (k <= p -> ls -> sz) return kth(p -> ls, k);
133         return kth(p -> rs, k - p -> ls -> sz - 1);
134     }
135 };
136  
137 int n, m;
138 int a[N];
139  
140 int main() {
141     using namespace treap;
142     int i;
143     char st[10];
144     n = read(), m = read();
145     for (i = 1; i <= n; ++i) a[i] = read();
146     null = new(0, NULL)node, null -> ls = null -> rs = null -> fa = null, null -> sz = 0;
147     build(T, null, 1, n, a);
148     for (i = 1; i <= m; ++i) {
149         scanf("%s", st + 1);
150         if (st[1] == T) move(read(), 0);
151         if (st[1] == B) move(read(), 1);
152         if (st[1] == I) move_to_mid(read(), read());
153         if (st[1] == A) printf("%d\n", get_rank(ptr[read()]) - 1);
154         if (st[1] == Q) printf("%d\n", kth(T, read()));
155     }
156     return 0;
157 }
158  
159 inline int read() {
160     static int x, sgn;
161     static char ch;
162     x = 0, sgn = 1, ch = getchar();
163     while (ch < 0 || 9 < ch) {
164         if (ch == -) sgn = -1;
165         ch = getchar();
166     }
167     while (0 <= ch && ch <= 9) {
168         x = x * 10 + ch - 0;
169         ch = getchar();
170     }
171     return sgn * x;
172 }
View Code

 

BZOJ1861 [Zjoi2006]Book 书架

标签:

原文地址:http://www.cnblogs.com/rausen/p/4480431.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!