平衡树

您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:

  1. 插入 x 数
  2. 删除 x 数(若有多个相同的数,因只删除一个)
  3. 查询 x 数的排名(排名定义为比当前数小的数的个数 +1 )
  4. 查询排名为 x 的数
  5. x 的前驱(前驱定义为小于 x,且最大的数)
  6. x 的后继(后继定义为大于 x,且最小的数)

#define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<cstring> #include<stdio.h> #include<algorithm> #include<map> #include<queue> #include<set> #include <sstream> #include<vector> #include<cmath> #include<stack> #include<random> using namespace std; #define io ios::sync_with_stdio(0),cin.tie(0) #define ms(arr) memset(arr,0,sizeof(arr)) #define LD long double #define LL long long #define PI acos(-1.0) #define INF 0x3f3f3f3f #define inf 1<<30 #define ull unsigned long long const int Mod = 998244353; const int maxn=1e5+5; std::mt19937 rnd(233); struct node { int l,r; int val,key; int size; }fhq[maxn]; int cnt,root; inline int newnode(int val) { fhq[++cnt].val=val; fhq[cnt].key=rnd(); fhq[cnt].size=1; return cnt; } inline void update(int now) { fhq[now].size=fhq[fhq[now].l].size+fhq[fhq[now].r].size+1; } void split(int now,int val,int &x,int &y) { if(!now) x=y=0; else { if(fhq[now].val<=val) { x=now; split(fhq[now].r,val,fhq[now].r,y); } else { y=now; split(fhq[now].l,val,x,fhq[now].l); } update(now); } } int merge(int x,int y) { if(!x||!y)return x+y; if(fhq[x].key>fhq[y].key) { fhq[x].r=merge(fhq[x].r,y); update(x); return x; } else { fhq[y].l=merge(x,fhq[y].l); update(y); return y; } } int x,y,z; void print(int x) { printf("%d\n", x); } inline void ins(int val) { split(root,val,x,y); root=merge(merge(x,newnode(val)),y); } inline void del(int val) { split(root,val,x,z); split(x,val-1,x,y); y=merge(fhq[y].l,fhq[y].r); root=merge(merge(x,y),z); } inline void getrank(int val) { split(root,val-1,x,y); print(fhq[x].size+1); root=merge(x,y); } inline void getnum(int rank) { int now=root; while(now) { if(fhq[fhq[now].l].size+1==rank) break; else if(fhq[fhq[now].l].size>=rank) now=fhq[now].l; else { rank-=fhq[fhq[now].l].size+1; now=fhq[now].r; } } print(fhq[now].val); } inline void pre(int val) { split(root,val-1,x,y); int now=x; while(fhq[now].r) now=fhq[now].r; print(fhq[now].val); root=merge(x,y); } inline void nxt(int val) { split(root,val,x,y); int now=y; while(fhq[now].l) now=fhq[now].l; print(fhq[now].val); root=merge(x,y); } int main() { int t; scanf("%d", &t); while (t--) { int opt, x; cin >> opt >> x; switch (opt) { case 1: ins(x); break; case 2: del(x); break; case 3: getrank(x); break; case 4: getnum(x); break; case 5: pre(x); break; case 6: nxt(x); break; } } }

 

posted @ 2021-03-11 17:51  夜灯长明  阅读(61)  评论(0编辑  收藏  举报