标签:
直接模拟过程就好了,维护数列的话用平衡树即可
注意要使用外部指针指向每个数出现的地方,否则没办法直接查找到
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 }
标签:
原文地址:http://www.cnblogs.com/rausen/p/4480431.html