P3369 【模板】普通平衡树 treap树旋转版
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 | #include<bits/stdc++.h> #define INF INT_MAX using namespace std; const int maxn=100010; int sum=0,R=0; int sz[maxn],v[maxn],num[maxn],rd[maxn],son[maxn][2]; //更新p子树的大小 void pushup( int p){ sz[p]=sz[son[p][0]]+sz[son[p][1]]+num[p]; } //旋转 void rot( int &p, int d){ int k=son[p][d^1]; son[p][d^1]=son[k][d]; son[k][d]=p; pushup(p); pushup(k); p=k; } //插入 void ins( int &p, int x){ if (!p){ p=++sum; sz[p]=num[p]=1; v[p]=x; rd[p]=rand(); return ; } if (v[p]==x){ num[p]++; sz[p]++; return ; } int d=(x>v[p]); //右子树 ins(son[p][d],x); if (rd[p]<rd[son[p][d]]) rot(p,d^1); pushup(p); } //删除 void del( int &p, int x){ if (!p) return ; if (x<v[p]) del(son[p][0],x); else if (x>v[p]) del(son[p][1],x); else { if (!son[p][0]&&!son[p][1]){ num[p]--;sz[p]--; if (!num[p]) p=0; } else if (!son[p][1]){ rot(p,1); del(son[p][1],x); } else if (!son[p][0]){ rot(p,0); del(son[p][0],x); } else { int d=(rd[son[p][0]]>rd[son[p][1]]); rot(p,d); del(son[p][d],x); } } pushup(p); } //x的排名 int get_rank( int p, int x){ if (!p) return 0; if (v[p]==x) return sz[son[p][0]]+1; if (v[p]<x) return sz[son[p][0]]+num[p]+get_rank(son[p][1],x); if (v[p]>x) return get_rank(son[p][0],x); } //排名x的值 int func_find( int p, int x){ if (!p) return 0; if (sz[son[p][0]]>=x) return func_find(son[p][0],x); else if (sz[son[p][0]]+num[p]<x) return func_find(son[p][1],x-num[p]-sz[son[p][0]]); else return v[p]; } //前驱 int pre( int p, int x){ if (!p) return -INF; if (v[p]>=x) return pre(son[p][0],x); else return max(v[p],pre(son[p][1],x)); } //后继 int suc( int p, int x){ if (!p) return INF; if (v[p]<=x) return suc(son[p][1],x); else return min(v[p],suc(son[p][0],x)); } int main() { int n,op,x; cin>>n; while (n--) { cin>>op>>x; if (op==1) ins(R,x); else if (op==2) del(R,x); else if (op==3) cout<<get_rank(R,x)<<endl; else if (op==4) cout<<func_find(R,x)<<endl; else if (op==5) cout<<pre(R,x)<<endl; else if (op==6) cout<<suc(R,x)<<endl; } } |
分类:
二叉搜索树BST,平衡树
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通