Treap

BST

\(v_i\) 表示点权,\(x\) 表示当前点,\(L\) 表示左子树,\(R\) 表示右子树

在普通二叉树的基础上多一个条件

对于 \(p\in L\),满足 \(v_p\leq v_x\)

对于 \(q\in R\),满足 \(v_x<v_q\)


Treap

但是这样如果 BST 是一条链的话就退化 \(O(n)\),而且很容易卡,考虑Treap

Treap 就是在普通 BST 基础上加上随机点权,随机点权满足堆性质,这样通过随机的堆可以保证树的均匀,即时间复杂度稳定


旋转 Treap

#include<bits/stdc++.h>

using namespace std;


struct node {
    int ls, rs;
    int val, dat;
    int cnt, siz;
    #define ls(p) tr[p].ls
    #define rs(p) tr[p].rs
    #define v(p) tr[p].val
    #define d(p) tr[p].dat
    #define c(p) tr[p].cnt
    #define s(p) tr[p].siz
};

const int INF=1<<30;
struct treap {
    int top, rt;
    vector<node> tr;
    int nnew(int val) {
        v(++top)=val;
        d(top)=rand();
        c(top)=s(top)=1;
        return top;
    }
    void pushup(int p) {
        s(p)=s(ls(p))+s(rs(p))+c(p);
    }
    void build(int siz) {
    	tr.resize(siz+1);
        rt=nnew(-INF);
        rs(rt)=nnew(INF);
        pushup(rt);
    }
    int getrk(int p,int val) {
        if(p==0) return 0;
        if(val==v(p)) return s(ls(p))+1;
        if(val<v(p)) return getrk(ls(p),val);
        return getrk(rs(p),val)+s(ls(p))+c(p);
    }
    int getrk(int val) {
    	return getrk(rt,val)-1;
    }
    int getval(int p,int rk) {
        if(p==0) return INF;
        if(rk<=s(ls(p))) return getval(ls(p),rk);
        if(rk<=s(ls(p))+c(p)) return v(p);
        return getval(rs(p),rk-s(ls(p))-c(p)); 
    }
    int getval(int rk) {
    	return getval(rt,rk+1);
    }
    void uplt(int &p) {
        int q=ls(p);
        ls(p)=rs(q), rs(q)=p, p=q;
        pushup(rs(p)), pushup(p);
    }
    void uprt(int &p) {
        int q=rs(p);
        rs(p)=ls(q), ls(q)=p, p=q;
        pushup(ls(p)), pushup(p);
    }
    void insert(int &p,int val) {
        if(p==0) {
            p=nnew(val);
            return;
        }
        if(val==v(p)) {
            c(p)++, pushup(p);
            return;
        }
        if(val<v(p)) {
            insert(ls(p),val);
            if(d(p)<d(ls(p))) uplt(p);
        }
        else {
            insert(rs(p),val);
            if(d(p)<d(rs(p))) uprt(p);
        }
        pushup(p);
    }
    void insert(int val) {
    	insert(rt,val);
    }
    int getpre(int val) {
        int ans=1, p=rt;
        for( ; p; p=val<v(p)?ls(p):rs(p)) {
            if(val==v(p)) {
                if(ls(p)) {
                    for(p=ls(p); rs(p); p=rs(p));
                    ans=p;
                }
                break;
            }
            if(v(p)<val&&v(p)>v(ans)) ans=p;
        }
        return v(ans);
    }
    int getnxt(int val) {
        int ans=2, p=rt;
        for( ; p; p=val<v(p)?ls(p):rs(p)) {
            if(v(p)==val) {
                if(rs(p)) {
                    for(p=rs(p); ls(p); p=ls(p));
                    ans=p;
                }
                break;
            }
            if(v(p)>val&&v(p)<v(ans)) ans=p;
        }
        return v(ans);
    }
    void remove(int &p,int val) {
        if(p==0) return;
        if(val==v(p)) {
            if(c(p)>1) {
                c(p)--, pushup(p);
                return;
            } 
            if(ls(p)||rs(p)) {
                if(rs(p)==0||d(ls(p))>d(rs(p)))
                    uplt(p), remove(rs(p),val);
                else uprt(p), remove(ls(p),val);
                pushup(p); 
            }
            else p=0;
            return;
        }
        val<v(p)?remove(ls(p),val):remove(rs(p),val);
        pushup(p);
    }
	void remove(int val) {
		remove(rt,val);
	}
} qwq;
#include<bits/stdc++.h>
#define int long long
#define MN 101000 

using namespace std;

struct node {
	int ls, rs;
	int val, dat;
	int cnt, siz;
	#define ls(p) tr[p].ls
	#define rs(p) tr[p].rs
	#define v(p) tr[p].val
	#define d(p) tr[p].dat
	#define c(p) tr[p].cnt
	#define s(p) tr[p].siz
} tr[MN]; 

const int INF=(int)1<<60;
int top, rt;

int nnew(int val) {
	v(++top)=val;
	d(top)=rand();
	c(top)=s(top)=1;
	return top;
}

void pushup(int p) {
	s(p)=s(ls(p))+s(rs(p))+c(p);
}

void build() {
	rt=nnew(-INF);
	rs(rt)=nnew(INF);
	pushup(rt);
}

int getrk(int p,int val) {
	if(p==0) return 0;
	if(val==v(p)) return s(ls(p))+1;
	if(val<v(p)) return getrk(ls(p),val);
	return getrk(rs(p),val)+s(ls(p))+c(p);
}

int getval(int p,int rk) {
	if(p==0) return INF;
	if(rk<=s(ls(p))) return getval(ls(p),rk);
	if(rk<=s(ls(p))+c(p)) return v(p);
	return getval(rs(p),rk-s(ls(p))-c(p)); 
}

void uplt(int &p) {
	int q=ls(p);
	ls(p)=rs(q), rs(q)=p, p=q;
	pushup(rs(p)), pushup(p);
}

void uprt(int &p) {
	int q=rs(p);
	rs(p)=ls(q), ls(q)=p, p=q;
	pushup(ls(p)), pushup(p);
}

void insert(int &p,int val) {
	if(p==0) {
		p=nnew(val);
		return;
	}
	if(val==v(p)) {
		c(p)++, pushup(p);
		return;
	}
	if(val<v(p)) {
		insert(ls(p),val);
		if(d(p)<d(ls(p))) uplt(p);
	}
	else {
		insert(rs(p),val);
		if(d(p)<d(rs(p))) uprt(p);
	}
	pushup(p);
}

int getpre(int val) {
	int ans=1, p=rt;
	for( ; p; p=val<v(p)?ls(p):rs(p)) {
		if(val==v(p)) {
			if(ls(p)) {
				for(p=ls(p); rs(p); p=rs(p));
				ans=p;
			}
			break;
		}
		if(v(p)<val&&v(p)>v(ans)) ans=p;
	}
	return v(ans);
}

int getnxt(int val) {
	int ans=2, p=rt;
	for( ; p; p=val<v(p)?ls(p):rs(p)) {
		if(v(p)==val) {
			if(rs(p)) {
				for(p=rs(p); ls(p); p=ls(p));
				ans=p;
			}
			break;
		}
		if(v(p)>val&&v(p)<v(ans)) ans=p;
	}
	return v(ans);
}

void remove(int &p,int val) {
	if(p==0) return;
	if(val==v(p)) {
		if(c(p)>1) {
			c(p)--, pushup(p);
			return;
		} 
		if(ls(p)||rs(p)) {
			if(rs(p)==0||d(ls(p))>d(rs(p)))
				uplt(p), remove(rs(p),val);
			else uprt(p), remove(ls(p),val);
			pushup(p); 
		}
		else p=0;
		return;
	}
	val<v(p)?remove(ls(p),val):remove(rs(p),val);
	pushup(p);
}

signed main() {
	srand((unsigned)time(0));
	build(); int n;
	scanf("%lld", &n);
	while(n--) {
		int op, x;
		scanf("%lld%lld", &op, &x);
		if(op==1) insert(rt,x);
		if(op==2) remove(rt,x);
		if(op==3) printf("%lld\n", getrk(rt,x)-1);
		if(op==4) printf("%lld\n", getval(rt,x+1));
		if(op==5) printf("%lld\n", getpre(x));
		if(op==6) printf("%lld\n", getnxt(x));
	}
	return 0;
} 
#define int long long
#define MN 101000 
const int INF=(int)1<<60;
struct treap {
	struct node {
		int ls, rs;
		int val, dat;
		int cnt, siz;
		#define ls(p) tr[p].ls
		#define rs(p) tr[p].rs
		#define v(p) tr[p].val
		#define d(p) tr[p].dat
		#define c(p) tr[p].cnt
		#define s(p) tr[p].siz
	} tr[MN]; 
	int top, rt;
	int nnew(int val) {
		v(++top)=val;
		d(top)=rand();
		c(top)=s(top)=1;
		return top;
	}
	void pushup(int p) {
		s(p)=s(ls(p))+s(rs(p))+c(p);
	}
	void build() {
		rt=nnew(-INF);
		rs(rt)=nnew(INF);
		pushup(rt);
	}
	int getrk(int p,int val) {
		if(p==0) return 0;
		if(val==v(p)) return s(ls(p))+1;
		if(val<v(p)) return getrk(ls(p),val);
		return getrk(rs(p),val)+s(ls(p))+c(p);
	}
	int getval(int p,int rk) {
		if(p==0) return INF;
		if(rk<=s(ls(p))) return getval(ls(p),rk);
		if(rk<=s(ls(p))+c(p)) return v(p);
		return getval(rs(p),rk-s(ls(p))-c(p)); 
	}
	void uplt(int &p) {
		int q=ls(p);
		ls(p)=rs(q), rs(q)=p, p=q;
		pushup(rs(p)), pushup(p);
	}
	void uprt(int &p) {
		int q=rs(p);
		rs(p)=ls(q), ls(q)=p, p=q;
		pushup(ls(p)), pushup(p);
	}
	void insert(int &p,int val) {
		if(p==0) {
			p=nnew(val);
			return;
		}
		if(val==v(p)) {
			c(p)++, pushup(p);
			return;
		}
		if(val<v(p)) {
			insert(ls(p),val);
			if(d(p)<d(ls(p))) uplt(p);
		}
		else {
			insert(rs(p),val);
			if(d(p)<d(rs(p))) uprt(p);
		}
		pushup(p);
	}
	int getpre(int val) {
		int ans=1, p=rt;
		for( ; p; p=val<v(p)?ls(p):rs(p)) {
			if(val==v(p)) {
				if(ls(p)) {
					for(p=ls(p); rs(p); p=rs(p));
					ans=p;
				}
				break;
			}
			if(v(p)<val&&v(p)>v(ans)) ans=p;
		}
		return v(ans);
	}
	int getnxt(int val) {
		int ans=2, p=rt;
		for( ; p; p=val<v(p)?ls(p):rs(p)) {
			if(v(p)==val) {
				if(rs(p)) {
					for(p=rs(p); ls(p); p=ls(p));
					ans=p;
				}
				break;
			}
			if(v(p)>val&&v(p)<v(ans)) ans=p;
		}
		return v(ans);
	}
	void remove(int &p,int val) {
		if(p==0) return;
		if(val==v(p)) {
			if(c(p)>1) {
				c(p)--, pushup(p);
				return;
			} 
			if(ls(p)||rs(p)) {
				if(rs(p)==0||d(ls(p))>d(rs(p)))
					uplt(p), remove(rs(p),val);
				else uprt(p), remove(ls(p),val);
				pushup(p); 
			}
			else p=0;
			return;
		}
		val<v(p)?remove(ls(p),val):remove(rs(p),val);
		pushup(p);
	}
} ;
posted @ 2023-08-12 22:47  Hypoxia571  阅读(10)  评论(0编辑  收藏  举报