• Splay模板


    此模板对于信息竞赛已经够用了,但是没有考虑建两棵或以上的Splay的情况,如果是需要实现可以稍微改一下

    纪念一下曾经的Notonlysuccess,我从那里学会了线段树和splay,可惜现在好像上不去了……

    这段代码作为模板也挺不错的,自我感觉可扩展性良好

    #include <cstdio>
    #define MAXN 100010
    using namespace std;
    
    int n;
    int root, node;
    int parent[MAXN], child[MAXN][2];
    int weight[MAXN], size[MAXN], count[MAXN];
    int trash[MAXN], top;
    
    inline void update(int x) {
    	size[x] = count[x] + size[child[x][0]] + size[child[x][1]];
    }
    
    inline void rotate(int x) {
    	int y = parent[x]; bool dir = child[y][0] == x;
    	if (child[y][!dir] = child[x][dir]) parent[child[x][dir]] = y;
    	if (parent[x] = parent[y]) child[parent[y]][child[parent[y]][1] == y] = x;
    	update(child[x][dir] = y); parent[y] = x;
    }
    
    inline void splay(int x, int goal) {
    	for (int y = parent[x]; y ^ goal; rotate(x), y = parent[x])
    		if (parent[y] ^ goal) rotate(child[y][child[parent[y]][0] == y] ? x : y);
    	update(x); if (!goal) root = x;
    }
    
    inline void new_node(int w, int &x, int pre) {
    	if (top) x = trash[--top]; else x = ++node;
    	child[x][0] = child[x][1] = 0;
    	count[x] = size[x] = 1;
    	parent[x] = pre;
    	weight[x] = w;
    }
    
    inline void insert(int value) {
    	int x = root;
    	if (size[x]) {
    		int y = parent[x];
    		while (x && value ^ weight[x])
    			++size[x], y = x, x = child[x][value > weight[x]];
    		bool dir = value > weight[y];
    		if (x) ++size[x], ++count[x];
    		else new_node(value, child[y][dir], y);
    	} else new_node(value, root, 0);
    }
    
    inline void remove(int value) {
    	int x = root;
    	while (x && value ^ weight[x])
    		x = child[x][value > weight[x]];
    	if (!x) return;
    	if (count[x] == 1) {
    		bool f = !child[x][0];
    		int y = child[x][f] ? child[x][f] : x;
    		while (child[y][!f]) y = child[y][!f];
    		bool b = child[parent[y]][1] == y;
    		if (parent[y]) child[parent[y]][b] = child[y][f];
    		if (child[y][f]) parent[child[y][f]] = parent[y];
    		weight[x] = weight[y]; count[x] = count[y];
    		for (count[x = y] = 0; x; x = parent[x]) update(x);
    		if (root == (trash[top++] = y)) root = 0;
    	} else for (--count[x]; x; x = parent[x]) --size[x];
    }
    
    inline int search(int w) {
    	int x = root;
    	while (x && w ^ weight[x])
    		x = child[x][w > weight[x]];
    	splay(x, root); return x;
    }
    
    inline int rank(int w) {
    	int x = root, ret = 0;
    	while (x && w ^ weight[x])
    		if (w < weight[x]) x = child[x][0];
    		else ret += count[x] + size[child[x][0]], x = child[x][1];
    	return ret + size[child[x][0]] + 1;
    }
    
    inline int find_kth(int k) {
    	if (k < 0 || k > size[root]) return 0;
    	int x = root;
    	while (k <= size[child[x][0]] || k > size[child[x][0]] + count[x])
    		if (k <= size[child[x][0]]) x = child[x][0];
    		else k -= size[child[x][0]] + count[x], x = child[x][1];
    	splay(x, 0); return x;
    }
    
    inline int prev(int w) {
    	int x = root, y = 0;
    	while (x)
    		if (w <= weight[x]) x = child[x][0];
    		else y = x, x = child[x][1];
    	if (y) splay(y, 0); return y;
    }
    
    inline int succ(int w) {
    	int x = root, y = 0;
    	while (x)
    		if (w >= weight[x]) x = child[x][1];
    		else y = x, x = child[x][0];
    	if (y) splay(y, 0); return y;
    }
    
    int main() {
    	for (scanf("%d", &n); n; --n) {
    		int op, x; scanf("%d%d", &op, &x);
    		switch (op) {
    			case 1: insert(x); break;
    			case 2: remove(x); break;
    			case 3: printf("%d
    ", rank(x)); break;
    			case 4: printf("%d
    ", weight[find_kth(x)]); break;
    			case 5: printf("%d
    ", weight[prev(x)]); break;
    			case 6: printf("%d
    ", weight[succ(x)]); break;
    		}
    	}
    	return 0;
    }
    

    这其实是BZOJ3224 Tyvj1728 普通平衡树的题解

    此题是极好的模板题,任何二叉搜索树都可以用它来检测代码的正确性

    对了那个类的Splay最近正在实现,因为一些特殊的原因没能在今天完成有点可惜

    大概明天就可以搞好,会发上来的

    实在是很累,先休息一晚上吧……到时候再推荐一下平衡树的入门题好了

    很可惜,身边的所有人都告诉我要以学业为重,这个博客可能无法持续更新

    真的,我觉得自己曾经的梦想幻灭,心很痛。

  • 相关阅读:
    字符串替换
    字符串查找
    字符串比较
    字节与字符串相互转换
    1365. How Many Numbers Are Smaller Than the Current Number
    1486. XOR Operation in an Array
    1431. Kids With the Greatest Number of Candies
    1470. Shuffle the Array
    1480. Running Sum of 1d Array
    【STM32H7教程】第56章 STM32H7的DMA2D应用之刷色块,位图和Alpha混合
  • 原文地址:https://www.cnblogs.com/johnsonyip/p/4338152.html
Copyright © 2020-2023  润新知