zoukankan      html  css  js  c++  java
  • 平衡树模板——splay,treap

    splay

    https://blog.csdn.net/clove_unique/article/details/50636361

    treap

    思维纲要:https://mubu.com/doc/w10-lxTDU0

    what's heap in treap?

    assign a random number to any new node in order to prevent its complexity from degenerating due to a sequence of ordered numbers to be inserted

    how to make heap?

    everytime we insert or delete, just keep the randomly assigned number in heap's order

    //reference:https://blog.csdn.net/Emm_Titan/article/details/103246344
    
    #include <bits/stdc++.h>	
    #define ll long long
    #define inf 0x3f3f3f3f
    using namespace std;
    const int maxn=1e6+10;//larger
    int num=0;//the number of the nodes
    int cnt[maxn];//the number of this node
    int key[maxn];//value
    int ran[maxn];//random value,               and we declare that the deeper the tree, the larger the node's ran'value will be
    int siz[maxn];//the number of its sons
    int son[maxn][2];//left right son
    void pushup(int x)
    {
    	siz[x]=siz[son[x][0]]+siz[son[x][1]]+cnt[x];
    }
    void rotate(int &x,int op)//mark op=0,1-->left right rotate    
    {
    	int p=son[x][!op];//save the heir
    	son[x][!op]=son[p][op];
    	son[p][op]=x;
    	pushup(x);//pushup the new son first
    	pushup(p);
    	x=p;//                               that's cool,because we also need to update the new node(new father)'s father,so we say p is the new x(p succeed x).and because "rotate" always company with "insert(son[k][op],x);" etc., so son[k][op] can be update。 
    }							
    void my_insert(int &k,int x)//&k:when successfully insert a new node,update it after recursion
    {
    	if (k==0)
    	{
    		k=++num;		
    		cnt[k]=1;
    		key[k]=x;
    		ran[k]=rand();
    		siz[k]=1;
    		return;
    	}
    	else if (key[k]==x)
    	{
    		cnt[k]++;
    		siz[k]++;
    		return;
    	}
    	int op=(x>key[k]);//to its left right son
    	my_insert(son[k][op],x);
    	if (ran[son[k][op]]<ran[k]) rotate(k,!op);//rotate from the the other size
    	pushup(k);	
    }
    void my_delete(int &k,int x)
    {
    	if (k==0) return;//this "x" does not exist
    	if (x!=key[k])
    	{
    		int op=(x>key[k]);
    		my_delete(son[k][op],x);
    		pushup(k);
    		/* TODO (#4#): no matter what, all need to pushup */
    		
    		return;
    	}
    	//if x==key[k]----means we get it
    	if (cnt[k]>1)
    	{
    		cnt[k]--;
    		siz[k]--;
    		pushup(k);
    		/* TODO (#2#): forget to pushup */
    				
    		return;
    	}
    	if (!son[k][0]&&son[k][1])
    	{
    		rotate(k,0);//only have right son,so we can only choose left rotate 
    		my_delete(son[k][0],x);
    	}
    	else if (son[k][0]&&!son[k][1])
    	{
    		rotate(k,1);
    		my_delete(son[k][1],x);		
    	}
    	else if (!son[k][0]&&!son[k][1])
    	{
    		cnt[k]--;
    		siz[k]--;
    		if (cnt[k]==0) k=0;
    		/* TODO (#3#): directly delete whole note */
    		
    	}
    	else
    	{
    		int op=(ran[son[k][0]]>ran[son[k][1]]);//if left son's ran'val is larger,we can only choose left rotate,or we break the ran'val rule
    		rotate(k,!op);
    		my_delete(son[k][!op],x);	
    			/* TODO (#1#): (!)op */	
    					
    	}
    	pushup(k);	
    }
    int my_find(int k,int x)//find key whose rank is x
    {
    	if (k==0) return 0;
    	if (siz[son[k][0]]>=x) return my_find(son[k][0],x);
    	else if (siz[son[k][0]]+cnt[k]<x)return my_find(son[k][1],x-siz[son[k][0]]-cnt[k]);
    	else return key[k];
    }
    int my_rank(int k,int x)//find the key's rank
    {
    	if (k==0) return 0;
    	if (key[k]==x) return siz[son[k][0]]+1;
    	if (key[k]>x) return my_rank(son[k][0],x);
    	return siz[son[k][0]]+cnt[k]+my_rank(son[k][1],x);
    }
    int my_lowerbound(int k,int x)
    {
    	if (k==0) return -inf;
    	if (key[k]>=x) return my_lowerbound(son[k][0],x);
    	else return max(key[k],my_lowerbound(son[k][1],x));
    }
    int my_upperbound(int k,int x)
    {
    	if (k==0) return inf;
    	if (key[k]<=x) return my_upperbound(son[k][1],x);
    	else return min(key[k],my_upperbound(son[k][0],x));
    }
    int main()
    {
    //	freopen("t.txt","r",stdin);
    	int n;
    	cin>>n;
    	memset(son,0,sizeof(son));
    	int root=0;
    	while (n--)
    	{
    		int opt,x;
    		scanf("%d%d",&opt,&x);
    		switch(opt)
    		{
    			case 1:my_insert(root,x);break;
    			case 2:my_delete(root,x);break;
    			case 3:printf("%d
    ",my_rank(root,x));break;
    			case 4:printf("%d
    ",my_find(root,x));break;
    			case 5:printf("%d
    ",my_lowerbound(root,x));break;
    			case 6:printf("%d
    ",my_upperbound(root,x));break;
    			default:break;
    		}
    	}	
    //	fclose(stdin);
    	return 0;
    
    }
    
  • 相关阅读:
    mybaits不能出现小于号
    结合rpyc使用python实现动态升级的方法
    secureCRT使用小贴士
    大数据的实时技术
    gnuplot使用
    Python3.4使用MySql
    Linux内存分配----SLAB
    WinInet:HTTPS 请求出现无效的证书颁发机构的处理
    正则表达式学习
    C++中static的全部作用
  • 原文地址:https://www.cnblogs.com/reshuffle/p/12245620.html
Copyright © 2011-2022 走看看