[bzoj1861][Zjoi2006]Book 书架
题目大意:有一串长度为$n$的序列,为$1\sim n$的一个排列,五个操作:
- $Top\;S:$把$S$放在序列开头
- $Bottom\;S:$把$S$放在序列结尾
- $Insert\;S\;T:$把$S$向后移动$T$个位置
- $Ask\;S:$询问$S$前有几个元素
- $Query\;S:$询问第$S$个元素是什么
题解:平衡树维护序列
卡点:无
C++ Code:
#include <cstdio>
#include <cstdlib>
#define maxn 80010
namespace Treap {
int P[maxn], sz[maxn];
int lc[maxn], rc[maxn], fa[maxn];
int root, idx;
int ta, tb, tmp, res, s;
inline int nw(int p) {
sz[p] = 1;
P[p] = rand();
return p;
}
inline int update(int rt) {
sz[rt] = sz[lc[rt]] + sz[rc[rt]] + 1;
fa[lc[rt]] = rt, fa[rc[rt]] = rt;
return rt;
}
inline void split(int rt, int k, int &x, int &y) {
if (!rt) x = y = 0;
else {
if (sz[lc[rt]] < k) split(rc[rt], k - sz[lc[rt]] - 1, rc[rt], y), x = update(rt);
else split(lc[rt], k, x, lc[rt]), y = update(rt);
}
}
inline int merge(int x, int y) {
if (!x || !y) return x | y;
if (P[x] > P[y]) {
rc[x] = merge(rc[x], y);
return update(x);
} else {
lc[y] = merge(x, lc[y]);
return update(y);
}
}
inline int gtrnk(int x) {
res = sz[lc[x]] + 1;
while (fa[x]) {
if (rc[fa[x]] == x) res += sz[lc[fa[x]]] + 1;
x = fa[x];
}
return res;
}
inline int k_th(int k, int p = root) {
while (true) {
if (sz[lc[p]] >= k) p = lc[p];
else {
if (sz[lc[p]] + 1 == k) return p;
else k -= sz[lc[p]] + 1, p = rc[p];
}
}
}
inline void insert(int p) {
if (!root) root = nw(p);
else {
root = merge(root, nw(p));
}
}
inline void top(int p) {
s = gtrnk(p);
split(root, s - 1, ta, tmp);
split(tmp, 1, tmp, tb);
root = merge(tmp, merge(ta, tb));
}
inline void bottom(int p) {
s = gtrnk(p);
split(root, s - 1, ta, tmp);
split(tmp, 1, tmp, tb);
root = merge(merge(ta, tb), tmp);
}
inline void Insert(int p, int pos) {
if (!pos) return ;
s = gtrnk(p);
split(root, s - 1, ta, tmp);
split(tmp, 1, tmp, tb);
root = merge(ta, tb);
s = s + pos - 1;
split(root, s, ta, tb);
root = merge(merge(ta, tmp), tb);
}
inline int ask(int p) {
return gtrnk(p) - 1;
}
inline int query(int p) {
return k_th(p);
}
}
int n, m;
int main() {
srand(20040826);
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i++) {
int a;
scanf("%d", &a);
Treap::insert(a);
}
while (m --> 0) {
char op[20];
int a, b;
scanf("%s%d", op, &a);
switch (*op) {
case 'T' : Treap::top(a); break;
case 'B' : Treap::bottom(a); break;
case 'I' : {
scanf("%d", &b);
Treap::Insert(a, b);
break;
}
case 'A' : printf("%d\n", Treap::ask(a)); break;
case 'Q' : printf("%d\n", Treap::query(a));
}
}
return 0;
}

浙公网安备 33010602011771号