zoukankan      html  css  js  c++  java
  • Treap

    其实(mathrm{Treap})最难的还是rotate函数

    • 把问题简化,其实就是处理当前节点的后两代子孙,两条边的问题

      1. root->root_grandson
      2. root_son->root

      就这两步修改

    • 然后因为进行第一步时,root对应的那个儿子会被grandson覆盖掉,所以要用一个tmpson存下来

    • 然后先将原本的root更新了,再将引用的root指针传给tmp,再将tmp更新即可,其他的inserterese结合代码都很易懂

    不过(mathrm{Treap})最重要的是不同的函数运用,这个就结合具体题目而言了

    现在手贱写了一个类,后悔了,太麻烦了

    #include<cstdio>
    #include<ctime>
    #include<cstdlib>
    #include<climits>
    
    const int maxn=1e5+2;
    
    class BT
    {
    	private:
    		struct Node
    		{
    			int v,idx,sz;
    			Node* son[2];
    			
    			void update()
    			{
    				sz=1;
    				
    				if( son[0] ) sz+=son[0]->sz;
    				if( son[1] ) sz+=son[1]->sz;return;
    			}
    		}Tree[maxn],*now=Tree,*root=NULL;
    		
    		void rotate(Node* &r,int d)
    		{
    			Node* tmp=r->son[d^1];
    			r->son[d^1]=tmp->son[d],tmp->son[d]=r;
    			
    			r->update();
    			r=tmp,r->update();return;
    		}
    	
    	public:
    		void insert(int v){real_insert(root,v);}
    		void real_insert(Node* &r,int v)
    		{
    			if(!r)
    			{
    				r=now++;
    				r->v=v,r->idx=rand(),r->son[0]=r->son[1]=NULL,r->sz=1;return;
    			}
    			
    			int d=( v>r->v );
    			real_insert(r->son[d],v);
    			
    			r->update();
    			if( r->idx > r->son[d]->idx ) rotate(r,d^1);return;
    		}
    		
    		void del(int v){real_del(root,v);return;}
    		void real_del(Node* &r,int v)
    		{
    			if(!r) return;
    			
    			if( r->v==v )
    			{
    				if( !r->son[0] and !r->son[1] ) r=NULL;
    				else if( !r->son[0] xor !r->son[1] )
    				{
    					int d=(r->son[1]!=NULL);
    					r=r->son[d];
    				}
    				else
    				{
    					int d=( r->son[0]->idx < r->son[1]->idx );
    					rotate(r,d),real_del(r->son[d],v);
    					
    					r->update();
    				}return;
    			}
    			
    			int d=( v>r->v );
    			real_del(r->son[d],v),r->update();
    		}
    		
    		int num_search(int v){return real_num_search(root,v);}
    		int real_num_search(Node* r,int v)
    		{
    			if(!r) return 1;
    			
    			if( v>r->v ) return ( (r->son[0]!=NULL)?r->son[0]->sz:0 ) + 1 + real_num_search(r->son[1],v);
    			else return real_num_search(r->son[0],v);
    		}
    		
    		int rank_search(int v){return real_rank_search(root,v);}
    		int real_rank_search(Node* r,int v)
    		{
    			int lsz=( r->son[0]!=NULL?r->son[0]->sz:0 );
    			
    			if( v==lsz+1 ) return r->v;
    			else if( v>lsz ) return real_rank_search(r->son[1],v-lsz-1);
    			else return real_rank_search(r->son[0],v);
    		}
    		
    		int pre(int v){return real_pre(root,v);}
    		int real_pre(Node* r,int v)
    		{
    			if(!r) return INT_MAX;
    			
    			if(r->v>=v) return real_pre(r->son[0],v);
    			else
    			{
    				int res=real_pre(r->son[1],v);
    				return ( res!=INT_MAX?res:r->v );
    			}
    		}
    		
    		int suf(int v){return real_suf(root,v);}
    		int real_suf(Node* r,int v)
    		{
    			if(!r) return INT_MAX;
    			
    			if(r->v<=v) return real_suf(r->son[1],v);
    			else
    			{
    				int res=real_suf(r->son[0],v);
    				return ( res!=INT_MAX?res:r->v );
    			}
    		}
    }bt;
    
    int main()
    {
    	srand(time(0));
    	
    	int n;scanf("%d",&n);
    	
    	while(n--)
    	{
    		int op,x;scanf("%d%d",&op,&x);
    		
    		if(op==1) bt.insert(x);
    		if(op==2) bt.del(x);
    		if(op==3) printf("%d
    ",bt.num_search(x));
    		if(op==4) printf("%d
    ",bt.rank_search(x));
    		if(op==5) printf("%d
    ",bt.pre(x));
    		if(op==6) printf("%d
    ",bt.suf(x));
    	}
    	
    	return 0;
    }
    
  • 相关阅读:
    Python定时任务sched(一)
    Python使用selenium进行爬虫(一)
    有关在python中使用Redis(二)
    有关JSOUP学习分享(一)
    jsoup爬虫,项目实战,欢迎收看
    有关在python中使用Redis(一)
    俄罗斯方块代码
    Android !No Launcher activity found!错误
    让jar程序在linux上一直执行(转)
    MyEclipse打包jar 并加入第三方包
  • 原文地址:https://www.cnblogs.com/info---tion/p/13378212.html
Copyright © 2011-2022 走看看