[bzoj1861][Zjoi2006]Book 书架

题目大意:有一串长度为$n$的序列,为$1\sim n$的一个排列,五个操作:

  1. $Top\;S:$把$S$放在序列开头
  2. $Bottom\;S:$把$S$放在序列结尾
  3. $Insert\;S\;T:$把$S$向后移动$T$个位置
  4. $Ask\;S:$询问$S$前有几个元素
  5. $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;
}

 

posted @ 2018-09-06 11:24  Memory_of_winter  阅读(180)  评论(0编辑  收藏  举报