zoukankan      html  css  js  c++  java
  • P3369 【模板】普通平衡树 题解

    Link

    P3369 【模板】普通平衡树

    Solve

    我很奇怪我为什么没有打平衡树的板子,今天一打到处都是问题,调到手费。

    打了一个Treap

    注意左旋,右旋,加入,删除操作要对父节点写&,方便根的传递

    其他都是板子,有空多打打,暖手wo~

    Code

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=100005,INF=1<<30;
    struct Treap{
    	int l,r;
    	int val,dat;
    	int cnt,size;
    }a[maxn];
    
    int tot,N,root;
    
    inline int read(){
    	int ret=0,f=1;char ch=getchar();
    	while(ch<'0'||ch>'9'){if(ch=='-')f=-f;ch=getchar();}
    	while(ch<='9'&&ch>='0')ret=ret*10+ch-'0',ch=getchar();
    	return ret*f;
    }
    
    int New(int val){
    	a[++tot].val=val;
    	a[tot].dat=rand();
    	a[tot].cnt=a[tot].size=1;
    	return tot;
    }
    
    void Update(int p){
    	a[p].size=a[a[p].l].size+a[a[p].r].size+a[p].cnt;
    }
    
    void Build(){
    	New(-INF);New(INF);
    	root=1;a[1].r=2;
    	Update(1);
    }
    
    int GetRankByVal(int p,int val){
    	if(p==0)
    		return 0;
    	if(val==a[p].val)
    		return a[a[p].l].size+1;
    	if(val<a[p].val)
    		return GetRankByVal(a[p].l,val);
    	return GetRankByVal(a[p].r,val)+a[a[p].l].size+a[p].cnt;
    }
    
    int GetValByRank(int p,int rank){
    	if(p==0)
    		return INF;
    	if(a[a[p].l].size>=rank)
    		return GetValByRank(a[p].l,rank);
    	if(a[a[p].l].size+a[p].cnt>=rank)
    		return a[p].val;
    	return GetValByRank(a[p].r,rank-a[a[p].l].size-a[p].cnt);
    }
    
    void zig(int &p){//right
    	int q=a[p].l;
    	a[p].l=a[q].r,a[q].r=p,p=q;
    	Update(a[p].r);Update(p);
    }
    
    void zag(int &p){
    	int q=a[p].r;
    	a[p].r=a[q].l;a[q].l=p;p=q;
    	Update(a[p].l);Update(p);
    }
    
    void Insert(int &p,int val){
    	if(p==0){p=New(val);return ;}
    	if(val==a[p].val){a[p].cnt++;Update(p);return ;}
    	if(val<a[p].val){
    		Insert(a[p].l,val);
    		if(a[p].dat<a[a[p].l].dat)zig(p);
    	}
    	else {
    		Insert(a[p].r,val);
    		if(a[p].dat<a[a[p].r].dat)zag(p);
    	}
    	Update(p);
    }
    
    int GetPre(int val){
    	int ans=1;//a[1].val=-INF;
    	int p=root;
    	while(p){
    		if(val==a[p].val){
    			if(a[p].l>0){
    				p=a[p].l;
    				while(a[p].r>0) p=a[p].r;
    				ans=p;
    			}
    			break;
    		}
    		if(a[p].val<val&&a[p].val>a[ans].val)ans=p;
    		p=val<a[p].val?a[p].l:a[p].r;
    	}
    	return a[ans].val;
    }
    
    int GetNext(int val){
    	int ans=2;
    	int p=root;
    	while(p){
    		if(val==a[p].val){
    			if(a[p].r>0){
    				p=a[p].r;
    				while(a[p].l>0)p=a[p].l;
    				ans=p;
    			}
    			break;
    		}
    		if(a[p].val>val&&a[p].val<a[ans].val)ans=p;
    		p=val<a[p].val?a[p].l:a[p].r;
    	}
    	return a[ans].val;
    }
    
    void Remove(int &p,int val){
    	if(p==0)return ;
    	if(val==a[p].val){
    		if(a[p].cnt>1){
    			a[p].cnt--;Update(p);
    			return ;
    		}
    		if(a[p].r||a[p].l){
    			if(a[p].r==0||a[a[p].l].dat>a[a[p].r].dat){
    				zig(p);Remove(a[p].r,val);
    			}
    			else {
    				zag(p);Remove(a[p].l,val);
    			}
    			Update(p);
    		}
    		else p=0;
    		return ;
    	}
    	val<a[p].val?Remove(a[p].l,val):Remove(a[p].r,val);
    	Update(p);
    }
    
    int main(){
    	freopen("Permutation.in","r",stdin);
    	freopen("Permutation.out","w",stdout);
    	Build();
    	N=read();
    	for(int i=1;i<=N;i++){
    		int op=read(),x=read();
    		     if(op==1) Insert(root,x);
    		else if(op==2) Remove(root,x);
    		else if(op==3) printf("%d
    ",GetRankByVal(root,x)-1);
    		else if(op==4) printf("%d
    ",GetValByRank(root,x+1));
    		else if(op==5) printf("%d
    ",GetPre(x));
    		else if(op==6) printf("%d
    ",GetNext(x));
    	}
    	return 0;
    }
    
  • 相关阅读:
    Win8系统 Python安装
    一些安卓开源框架整理
    Android 媒体键监听以及模拟媒体键盘的实现 demo
    android View 自动 GONE 问题
    Android 定时器TimerTask 简单使用
    关于Android studio 相对 eclipse 优点
    Java序列化与反序列化
    android shape的使用 边框
    Android Studio 修改 包名 package name
    Android WebView Long Press长按保存图片到手机
  • 原文地址:https://www.cnblogs.com/martian148/p/13895371.html
Copyright © 2011-2022 走看看