BZOJ-3224 普通平衡树
一道BST的练习题。
Treap版:
#include <cstdlib> #include <cstdio> #include <algorithm> #include <iostream> #include <cctype> #include <cstring> #define rep(i, l, r) for(int i=l; i<=r; i++) #define clr(x, c) memset(x, c, sizeof(x)) #define update(x) s[x]=s[l[x]]+s[r[x]]+1 #define maxn 100009 #define inf 0x7fffffff using namespace std; inline int read() { int x=0, f=1; char ch=getchar(); while (!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();} while (isdigit(ch)) {x=x*10+ch-'0'; ch=getchar();} return x*f; } int n=read(); int l[maxn], r[maxn], s[maxn], k[maxn], pr[maxn], roof, V; inline void Init(){srand(233); roof=V=0;} inline void Left(int &v) { int u=r[v]; r[v]=l[u], l[u]=v; update(v), update(u); v=u; } inline void Right(int &v) { int u=l[v]; l[v]=r[u], r[u]=v; update(v), update(u); v=u; } void Insert(int x, int &v) { if (!v) { v=++V; l[v]=r[v]=0, s[v]=1, k[v]=x, pr[v]=rand(); return; } if (x < k[v]) { Insert(x, l[v]); update(v); if (pr[l[v]] > pr[v]) Right(v); } else { Insert(x, r[v]); update(v); if (pr[r[v]] > pr[v]) Left(v); } } void Delete(int x, int &v) { if (x==k[v]) { if (!l[v]) {v=r[v]; return;} else if (!r[v]) {v=l[v]; return;} else if (pr[l[v]] > pr[r[v]]) {Right(v); Delete(x, r[v]);} else {Left(v); Delete(x, l[v]);} } else Delete(x, x<k[v] ? l[v] : r[v]); update(v); } int Rank(int x, int v) { if (!v) return 0; if (x>k[v]) return s[l[v]]+1+Rank(x, r[v]); else return Rank(x, l[v]); } int Select(int n, int v) { if (s[l[v]]==n) return k[v]; if (n>s[l[v]]) return Select(n-s[l[v]]-1, r[v]); else return Select(n, l[v]); } int Suf(int x) { int rec=inf; for(int v=roof; v; v=x<k[v] ? l[v] : r[v]) if (k[v]>x) rec=min(rec, k[v]); return rec; } int Pre(int x) { int rec=-inf; for(int v=roof; v; v=x<=k[v] ? l[v] : r[v]) if (k[v]<x) rec=max(rec, k[v]); return rec; } int main() { Init(); rep(i, 1, n) { int a=read(); if (a==1) Insert(read(), roof); else if (a==2) Delete(read(), roof); else if (a==3) printf("%d\n", Rank(read(), roof)+1); else if (a==4) printf("%d\n", Select(read()-1, roof)); else if (a==5) printf("%d\n", Pre(read())); else printf("%d\n", Suf(read())); } return 0; }