zoukankan      html  css  js  c++  java
  • BZOJ 1503 郁闷的出纳员 Splay

    这题由于每次都是对树全体进行操作,其实设置一个全局的延迟标记就好

    用到的操作主要是插入,删除子树,统计子树信息找第k大。

    感觉Splay可以灵活的把需要用到的节点提到根上或者是根的儿子这里还是很方便的。

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cstdlib>
    #include <climits>
    
    using namespace std;
    
    const int maxn = 1e6 + 10;
    
    int ch[maxn][2], val[maxn], size[maxn], chcnt, fa[maxn], root;
    char cmd[16];
    int n, min_val, tmp, tval, lcnt;
    
    void update(int x) {
    	size[x] = 1;
    	if (ch[x][0]) size[x] += size[ch[x][0]];
    	if (ch[x][1]) size[x] += size[ch[x][1]];
    }
    
    void rotate(int x, int d) {
    	int y = fa[x];
    	fa[ch[x][d]] = y; ch[y][d ^ 1] = ch[x][d];
    	if (fa[y]) ch[fa[y]][y == ch[fa[y]][1]] = x;
    	fa[x] = fa[y]; fa[y] = x;
    	ch[x][d] = y;
    	update(x); update(y);
    }
    
    void splay(int x, int goal) {
    	while (fa[x] != goal) {
    		int y = fa[x], d = (x == ch[y][1]);
    		if (fa[y] == goal) rotate(x, d ^ 1);
    		else {
    			int z = fa[y], d1 = (y == ch[z][1]);
    			if (d == d1) {
    				rotate(y, d ^ 1); rotate(x, d ^ 1);
    			}
    			else {
    				rotate(x, d ^ 1); rotate(x, d1 ^ 1);
    			}
    		}
    	}
    	if (goal == 0) root = x;
    }
    
    int findkth(int x, int k) {
    	if (k <= 0 || k > size[x] || x == 0) return -1;
    	int rsize = (ch[x][1] == 0 ? 0 : size[ch[x][1]]);
    	if (rsize >= k) return findkth(ch[x][1], k);
    	else if (k == rsize + 1) return x;
    	else return findkth(ch[x][0], k - 1 - rsize);
    }
    
    int newNode(int &r, int father, int v) {
    	r = ++chcnt;
    	ch[r][0] = ch[r][1] = 0;
    	fa[r] = father; val[r] = v;
    	size[r] = 1;
    	return r;
    }
    
    int insert(int v) {
    	int u = root;
    	if (u == 0) {
    		newNode(root, 0, v); return root;
    	}
    	while (ch[u][v > val[u]]) u = ch[u][v > val[u]];
    	int r = newNode(ch[u][v > val[u]], u, v);
    	update(u);
    	splay(r, 0);
    	return r;
    }
    
    void remove_tree(int x) {
    	if (x == 0) return;
    	if (x == root) root = 0;
    	else {
    		ch[fa[x]][x == ch[fa[x]][1]] = 0;
    		x = fa[x]; fa[x] = 0;
    		while (x) {
    			update(x); x = fa[x];
    		}
    	}
    }
    
    void debug(int root) {
    	int lc = ch[root][0], rc = ch[root][1];
    	printf("当前节点:%d(val = %d), lch: %d(val = %d), rch %d(val = %d), fa is %d
    ",
    		root, val[root], lc, val[lc], rc, val[rc], fa[root]);
    	if (lc) debug(lc);
    	if (rc) debug(rc);
    }
    
    int main() {
    	while (scanf("%d%d", &n, &min_val) != EOF) {
    		chcnt = root = tmp = lcnt = 0;
    		for (int i = 1; i <= n; i++) {
    			scanf("%s%d", cmd, &tval);
    			if (cmd[0] == 'I') {
    				if (tval < min_val) continue;
    				insert(tval - tmp);
    			}
    			else if (cmd[0] == 'A') tmp += tval;
    			else if (cmd[0] == 'S') {
    				tmp -= tval;
    				insert(min_val - tmp);
    				lcnt += size[ch[root][0]];
    				remove_tree(ch[root][0]);
    				fa[ch[root][1]] = 0;
    				root = ch[root][1];
    			}
    			else {
    				int ret = findkth(root, tval);
    				printf("%d
    ", ret == -1 ? -1 : val[ret] + tmp);
    			}
    		}
    		printf("%d
    ", lcnt);
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    sql server:Monty Hall problem (蒙提霍尔问题)
    sql server: Graphs, Trees, Hierarchies and Recursive Queries
    csharp:SMO run sql script
    csharp: sum columns or rows in a dataTable
    sql server: quering roles, schemas, users,logins
    sql: Query to Display Foreign Key Relationships and Name of the Constraint for Each Table in Database
    Hadoop基本概念
    OVS架构解析
    Linux下实现修改IP选项字段
    linux下实现UDP通信
  • 原文地址:https://www.cnblogs.com/rolight/p/4277172.html
Copyright © 2011-2022 走看看