平衡树 2

板子

无旋Treap

点击查看代码
#include <bits/stdc++.h>
using namespace std;
const int o=2222222;
struct Treap{
    struct node{
        int l,r;
        int size;
        int val;
        int k;
    }t[o];
    int tot,root;
    int add(int x){
        tot++;
        t[tot].val=x;
        t[tot].k=rand();
        t[tot].size=1;
        return tot;
    }
    void pushup(int x){
        t[x].size=t[t[x].l].size+t[t[x].r].size+1;
    }
    void split(int x,int &l,int &r,int v){
        if(x==0){
            l=r=0;
            return ;
        }
        if(v<t[x].val){
            split(t[x].l,l,t[x].l,v);
            r=x;
            pushup(r);
            return;
        }
        else{
            split(t[x].r,t[x].r,r,v);
            l=x;
            pushup(l);
            return;
        }
    }
    int merge(int x,int y){
        if(!y||!x){
            return x|y;
        }
        if(t[x].k<t[y].k){
            t[x].r=merge(t[x].r,y);
            pushup(x);
            return x;
        }
        else{
            t[y].l=merge(x,t[y].l);
            pushup(y);
            return y;
        }
    }
    void pop(int x){
        int l,m,r;
        split(root,l,r,x);
        split(l,l,m,x-1);
        m=merge(t[m].l,t[m].r);
        r=merge(merge(l,m),r);
    }
    int kthval(int x,int id){
        if(t[t[x].l].size+1==id){
            return t[x].val;
        }
        if(t[t[x].l].size>=id){
            return kthval(t[x].l,id);
        }
        return kthval(t[x].r,id-t[t[x].l].size-1);
    }
    int rank(int x){
        int l=0,r=0,ans=0;
        split(root,l,r,x-1);
        ans=t[l].size+1;
        root=merge(l,r);
        return ans;
    }
    int pre(int x){
        int l=0,r=0,ans=0;
        split(root,l,r,x-1);
        ans=kthval(l,t[l].size);
        root=merge(l,r);
        return ans;
    }
    int next(int x){
        int l=0,r=0,ans=0;
        split(root,l,r,x-1);
        ans=kthval(r,1);
        root=merge(l,r);
        return ans;
    }
}T;
int main(){
    return 0;
}

Splay

点击查看代码

int root,N,tot;
struct SplayTree{
	struct node{
		int ch[2];
		int fa;
		int cnt;
		int val;
		int son;
	}t[o];
	void pushup(int x){//infomation
		t[x].son=t[t[x].ch[1]].son+t[t[x].ch[0]].son+t[x].cnt;
	}
	void rotate(int x){//
		int y=t[x].fa;
		int z=t[y].fa;
		int k=t[y].ch[1]==x;
		t[z].ch[t[z].ch[1]==y]=x;
		t[x].fa=z;
		t[y].ch[k]=t[x].ch[k^1];
		t[t[x].ch[k^1]].fa=y;
		t[x].ch[k^1]=y;
		t[y].fa=x;
		/*info*/
		pushup(y);
		pushup(x); 
	}
	void splay(int x,int to){
		while(t[x].fa!=to){
			int y=t[x].fa;
			int z=t[y].fa;
			if(z!=to){
				if((t[y].ch[0]==x)^(t[z].ch[0]==y)){
					rotate(x);
				}
				else{
					rotate(y);
				}
			}
			rotate(x);
		}
		if(to==0){
			root=x;
		}
	}
	void add(int x){
		int u=root,fa=0;
		while(u&&t[u].val!=x){
			fa=u;
			u=t[u].ch[x>t[u].val];
		}
		if(u){
			t[u].cnt++;
		}
		else{
			u=++tot;
			if(fa){
				t[fa].ch[x>t[fa].val]=u;
			}
			t[tot].ch[0]=0;
			t[tot].ch[1]=0;
			t[tot].fa=fa;
			t[tot].val=x;
			t[tot].cnt=1;
			t[tot].son=1;
		}
		splay(u,0);
	}
	void find(int x){
		int u=root;
		if(!u){
			return ;
		}
		while(t[u].ch[x>t[u].val]&&x!=t[u].val){
			u=t[u].ch[x>t[u].val];
		}
		splay(u,0);
	//	return t[t[root].ch[0]].son;
	}
	int next(int x,int f){
		find(x);
		int u=root;
		if((t[u].val>x&&f)||(t[u].val<x&&!f)){
			return u;
		}
		u=t[u].ch[f];
		while(t[u].ch[f^1]){
			u=t[u].ch[f^1];
		}
		return u;
		//return t[u].val;
	}
	void pop(int x){
		int l=next(x,0);
		int n=next(x,1);
		splay(l,0);
		splay(n,l);
		int del=t[n].ch[0];
		if(t[del].cnt>1){
			t[del].cnt--;
			splay(del,0);
		}
		else{
			t[n].ch[0]=0;
		}
	}
	int rank(int x){
		int u=root;
		if(t[u].son<x){
			return -1;
		}
		while(1){
			int y=t[u].ch[0];
			if(x>t[y].son+t[u].cnt){
				x-=t[y].son+t[u].cnt;
				u=t[u].ch[1];
			}
			else{
				if(t[y].son>=x){
					u=y;
				}
				else{
					return t[u].val;	
				}
			}
		}
	}
}S;

Treap

只会有旋555

Splay

非常熟悉的Splay
就平衡而言:
这玩意实际上不是非常平衡
因为是靠结构维护的平衡,所以不会非常平衡
不过因为有个叫摊还的,所以这玩意在最坏情况下是均摊单次O(logn)
然后就是Splay了
Splay的旋转操作是双旋,即Splay:
首先是1字形:
这种旋两次x节点
然后是之字形:
这种先旋一次fax再旋x
然后是单旋转,即Rotate:
核心一个事情是维护BST性质,
主要就是对于一个之字形而言:
一个之字应该成为与之反向的之字

posted @   2K22  阅读(16)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
点击右上角即可分享
微信分享提示