P3369 【模板】普通平衡树 —— Treap FHQtreap
【模板】普通平衡树
题目描述
您需要动态地维护一个可重集合 ,并且提供以下操作:
- 向 中插入一个数 。
- 从 中删除一个数 (若有多个相同的数,应只删除一个)。
- 查询 中有多少个数比 小,并且将得到的答案加一。
- 查询如果将 从小到大排列后,排名位于第 位的数。
- 查询 中 的前驱(前驱定义为小于 ,且最大的数)。
- 查询 中 的后继(后继定义为大于 ,且最小的数)。
对于操作 3,5,6,不保证当前可重集中存在数 。
输入格式
第一行为 ,表示操作的个数,下面 行每行有两个数 和 , 表示操作的序号()
输出格式
对于操作 每行输出一个数,表示对应答案。
样例 #1
样例输入 #1
10 1 106465 4 1 1 317721 1 460929 1 644985 1 84185 1 89851 6 81968 1 492737 5 493598
样例输出 #1
106465 84185 492737
提示
【数据范围】
对于 的数据,,
来源:Tyvj1728 原名:普通平衡树
在此鸣谢
分析
模板
#include<bits/stdc++.h> using namespace std; const int N=1e5+100,M=1e6+100; struct node { int lc,rc,pre,val,siz; }t[N]; int tot,root,n; void create(int x) { ++tot; t[tot].lc=t[tot].rc=0; t[tot].val=x; t[tot].siz=1; t[tot].pre=rand(); } void upd(int x) { t[x].siz=t[t[x].lc].siz+t[t[x].rc].siz+1; } void split(int u,int x,int &L,int &R) { if(u==0){L=R=0;return ;} if(t[u].val<=x) { L=u; split(t[u].rc,x,t[u].rc,R); } else { R=u; split(t[u].lc,x,L,t[u].lc); } upd(u); } int merg(int L,int R) { if(L==0 || R==0)return L+R; if(t[L].pre>t[R].pre) { t[L].rc=merg(t[L].rc,R); upd(L); return L; } else { t[R].lc=merg(L,t[R].lc); upd(R); return R; } } void inser(int x) { int L=0,R=0; create(x); split(root,x,L,R); L=merg(L,tot); root=merg(L,R); } void del(int x) { int L=0,R=0,nw=0; split(root,x,L,R); split(L,x-1,L,nw); nw=merg(t[nw].lc,t[nw].rc); L=merg(L,nw); root=merg(L,R); } int finx(int x) { int L=0,R=0,nw=0; split(root,x-1,L,R); nw=t[L].siz+1; root=merg(L,R); return nw; } int rk(int u,int k) { if(t[t[u].lc].siz+1==k)return u; if(t[t[u].lc].siz>=k)return rk(t[u].lc,k); else return rk(t[u].rc,k-t[t[u].lc].siz-1); } int pre_x(int x) { int L=0,R=0,nw=0; split(root,x-1,L,R);///L==0 -->RE nw=t[ rk(L,t[L].siz) ] .val; root=merg(L,R); return nw; } int suf_x(int x) { int L=0,R=0,nw=0; split(root,x,L,R); nw=t[ rk(R,1) ] .val; root=merg(L,R); return nw; } void work() { cin>>n; int opt,x; while(n--) { scanf("%d%d",&opt,&x); if(opt==1)inser(x); else if(opt==2)del(x); else { int ans=0; if(opt==3)ans=finx(x); else if(opt==4)ans=t[rk(root,x)].val; else if(opt==5)ans=pre_x(x); else ans=suf_x(x); printf("%d\n",ans); } } } int main() { work(); return 0; }
本文来自博客园,作者:Glowingfire,转载请注明原文链接:https://www.cnblogs.com/Glowingfire/p/18576060
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!