zoukankan      html  css  js  c++  java
  • _bzoj3224 Tyvj 1728 普通平衡树【Splay】

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=3224

    保存splay模版

    一刻不停写了一个小时多一点,幸好一遍过了!(其实带着freopen wa了一次)

    添加一个易出bug的地方叭(鉴于曾经有次这么错过):此题平衡树里可以用重复值,我是用tm保存出现的次数,因此在求第k大时,千万小心循环结束条件!

    #include <cstdio>
    #include <algorithm>
    
    const int maxn = 200005;
    
    int fa[maxn], ch[maxn][2], key[maxn], tm[maxn], siz[maxn], root, cnt, t1, t2;
    
    inline void pushup(int x) {
    	siz[x] = siz[ch[x][0]] + siz[ch[x][1]] + tm[x];
    }
    inline void rotate(int x) {
    	int y = fa[x];
    	if (y == ch[fa[y]][0]) {
    		ch[fa[y]][0] = x;
    	}
    	else {
    		ch[fa[y]][1] = x;
    	}
    	fa[x] = fa[y];
    	int dir = x == ch[y][1];
    	ch[y][dir] = ch[x][dir ^ 1];
    	fa[ch[x][dir ^ 1]] = y;
    	ch[x][dir ^ 1] = y;
    	fa[y] = x;
    	pushup(y);
    	pushup(x);
    }
    inline void splay(int x) {
    	int p, flag1, flag2;
    	while (fa[x]) {
    		p = fa[x];
    		if (!fa[p]) {
    			rotate(x);
    		}
    		else {
    			flag1 = x == ch[p][1];
    			flag2 = p == ch[fa[p]][1];
    			if (flag1 ^ flag2) {
    				rotate(x);
    			}
    			else {
    				rotate(p);
    			}
    			rotate(x);
    		}
    	}
    	root = x;
    }
    bool ist(int x, int val, int p, int dir) {
    	if (!x) {
    		key[++cnt] = val;
    		tm[cnt] = 1;
    		siz[cnt] = 1;
    		fa[cnt] = p;
    		ch[p][dir] = cnt;
    		return true;
    	}
    	if (val < key[x]) {
    		bool rt = ist(ch[x][0], val, x, 0);
    		pushup(x);
    		return rt;
    	}
    	else if (val > key[x]) {
    		bool rt = ist(ch[x][1], val, x, 1);
    		pushup(x);
    		return rt;
    	}
    	else {
    		++tm[x];
    		++siz[x];
    		return false;
    	}
    }
    inline int fndmin(int x) {
    	int rt = x, mn = key[x];
    	for (int i = ch[x][0]; i; i = ch[i][0]) {
    		if (mn > key[i]) {
    			mn = key[rt = i];
    		}
    	}
    	return rt;
    }
    inline int fndmax(int x) {
    	int rt = x, mx = key[x];
    	for (int i = ch[x][1]; i; i = ch[i][1]) {
    		if (mx < key[i]) {
    			mx = key[rt = i];
    		}
    	}
    	return rt;
    }
    void del(int x, int value) {
    	if (!x) {
    		return;
    	}
    	if (value < key[x]) {
    		del(ch[x][0], value);
    		pushup(x);
    	}
    	else if (value > key[x]) {
    		del(ch[x][1], value);
    		pushup(x);
    	}
    	else if (tm[x] > 1) {
    		--tm[x];
    		--siz[x];
    	}
    	else {
    		splay(x);
    		fa[ch[x][0]] = fa[ch[x][1]] = 0;
    		if (!ch[x][0]) {
    			root = ch[x][1];
    		}
    		else if (!ch[x][1]) {
    			root = ch[x][0];
    		}
    		else {
    			root = fndmax(ch[x][0]);
    			splay(root);
    			fa[ch[x][1]] = root;
    			ch[root][1] = ch[x][1];
    			pushup(root);
    		}
    	}
    }
    inline int qianqu(int val) {
    	if (ist(root, val, 0, 0)) {
    		splay(cnt);
    	}
    	int x = root;
    	while (val != key[x]) {
    		x = ch[x][val > key[x]];
    	}
    	splay(x);
    	x = key[fndmax(ch[x][0])];
    	del(root, val);
    	return x;
    }
    inline int houji(int val) {
    	if (ist(root, val, 0, 0)) {
    		splay(cnt);
    	}
    	int x = root;
    	while (val != key[x]) {
    		x = ch[x][val > key[x]];
    	}
    	splay(x);
    	x = key[fndmin(ch[x][1])];
    	del(root, val);
    	return x;
    }
    inline int getrank(int val) {
    	int x = root;
    	while (key[x] != val) {
    		x = ch[x][val > key[x]];
    	}
    	splay(x);
    	return siz[ch[x][0]] + 1;
    }
    inline int getnum(int rank) {
    	int x = root;
    	while (rank <= siz[ch[x][0]] || rank > siz[ch[x][0]] + tm[x]) {
    		if (rank <= siz[ch[x][0]]) {
    			x = ch[x][0];
    		}
    		else {
    			rank -= siz[ch[x][0]] + tm[x];
    			x = ch[x][1];
    		}
    	}
    	return key[x];
    }
    
    int main(void) {
    	int n;
    	scanf("%d", &n);
    	while (n--) {
    		scanf("%d%d", &t1, &t2);
    		if (t1 == 1) {
    			if (ist(root, t2, 0, 0)) {
    				splay(cnt);
    			}
    		}
    		else if (t1 == 2) {
    			del(root, t2);
    		}
    		else if (t1 == 3) {
    			printf("%d
    ", getrank(t2));
    		}
    		else if (t1 == 4) {
    			printf("%d
    ", getnum(t2));
    		}
    		else if (t1 == 5) {
    			printf("%d
    ", qianqu(t2));
    		}
    		else {
    			printf("%d
    ", houji(t2));
    		}
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    hdoj-1005-Number Sequences
    FOJ-1058-粗心的物理学家
    程序设计第三次作业附加 代码规范
    简单数论
    FOJ-1001-Duplicate Pair
    链表初尝试-链表的构建与输出-指针
    函数递归简单题-hdoj-2044 2018-一只小蜜蜂 母牛的故事
    电路与电子学-第一章直流电路分析方法小概括
    DFS回溯-函数递归-xiaoz triangles
    进制转换 hdoj-2031
  • 原文地址:https://www.cnblogs.com/ciao-sora/p/6146958.html
Copyright © 2011-2022 走看看