bzoj3224 Tyvj1728—普通平衡树
Posted MashiroSky
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj3224 Tyvj1728—普通平衡树相关的知识,希望对你有一定的参考价值。
http://www.lydsy.com/JudgeOnline/problem.php?id=3224 (题目链接)
题意
1. 插入x数;2. 删除x数(若有多个相同的数,因只删除一个);3. 查询x数的排名(若有多个相同的数,因输出最小的排名);4. 查询排名为x的数;5. 求x的前驱(前驱定义为小于x,且最大的数);6. 求x的后继(后继定义为大于x,且最小的数)
Solution
treap板子。右转光勋总结→_→:平衡树
细节
一个节点还统计了这个数出现了几次,然后询问排名前驱后继什么的写的我蛋都要碎了T_T
旋转treap
// bzoj3224 #include<algorithm> #include<iostream> #include<cstdlib> #include<cstring> #include<cstdio> #include<cmath> #define LL long long #define inf 2147483640 #define Pi acos(-1.0) #define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout) using namespace std; const int maxn=100010; int n,sz,Dargen; struct node { int son[2],size,val,rnd,w; int& operator [] (int x) {return son[x];} }tr[maxn]; void pushup(int k) { tr[k].size=tr[tr[k][0]].size+tr[tr[k][1]].size+tr[k].w; } void rotate(int &x,int p) { //记得& int y=tr[x][p]; tr[x][p]=tr[y][p^1];tr[y][p^1]=x;x=y; //记得写x=y pushup(tr[y][p^1]);pushup(y); } void insert(int &k,int x) { if (!k) {tr[k=++sz].val=x;tr[k].rnd=rand();tr[k].size=tr[k].w=1;return;} int p=x>tr[k].val;tr[k].size++; if (tr[k].val==x) {tr[k].w++;return;} insert(tr[k][p],x); if (tr[tr[k][p]].rnd>tr[k].rnd) rotate(k,p); } void erase(int &k,int x) { if (k==0) return; if (tr[k].val==x) { if (tr[k].w>1) {tr[k].w--;tr[k].size--;return;} if (tr[k][0]*tr[k][1]==0) k=tr[k][0]+tr[k][1]; else rotate(k,tr[tr[k][0]].rnd<tr[tr[k][1]].rnd),erase(k,x); } else if (x<tr[k].val) tr[k].size--,erase(tr[k][0],x); else tr[k].size--,erase(tr[k][1],x); } int find(int k,int x) { if (!k) return 0; if (tr[tr[k][0]].size<x && x<=tr[tr[k][0]].size+tr[k].w) return tr[k].val; else if (x<=tr[tr[k][0]].size) return find(tr[k][0],x); else return find(tr[k][1],x-tr[tr[k][0]].size-tr[k].w); } int rank(int k,int x) { if (!k) return 0; if (tr[k].val==x) return tr[tr[k][0]].size+1; if (x<=tr[k].val) return rank(tr[k][0],x); else return rank(tr[k][1],x)+tr[tr[k][0]].size+tr[k].w; } int main() { scanf("%d",&n); for (int op,x,i=1;i<=n;i++) { scanf("%d%d",&op,&x); if (op==1) insert(Dargen,x); if (op==2) erase(Dargen,x); if (op==3) printf("%d\n",rank(Dargen,x)); if (op==4) printf("%d\n",find(Dargen,x)); if (op==5) printf("%d\n",find(Dargen,rank(Dargen,x-1))); if (op==6) { if (find(Dargen,rank(Dargen,x+1))==x+1) printf("%d\n",x+1); else printf("%d\n",find(Dargen,rank(Dargen,x+1)+1)); } } return 0; }
以上是关于bzoj3224 Tyvj1728—普通平衡树的主要内容,如果未能解决你的问题,请参考以下文章
bzoj3224: Tyvj 1728 普通平衡树 treap