• [bzoj1861][Zjoi2006]Book 书架


    题目大意:有一串长度为$n$的序列,为$1sim 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
    ", Treap::ask(a)); break;
    			case 'Q' : printf("%d
    ", Treap::query(a));
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    Centos6.8下设置gitlab服务开机自启动,关闭防火墙开机自启动
    gitlab设置SSH key
    在centos6.8下安装gitlab遇到的坑
    recyclerView中的方法
    ListView中的方法
    tcp断开时分几步
    get,post区别
    cookie是什么,在什么地方会用到
    http和https的区别
    keystore是个嘛东西
  • 原文地址:https://www.cnblogs.com/Memory-of-winter/p/9597309.html
Copyright © 2020-2023  润新知