无旋treap hfq-treap
怎么代码都这么长。。。
#include<iostream> #include<stdio.h> #include<string.h> #include<algorithm> #include<random> using namespace std; const int maxn = 1e5+5; struct node{ int l,r; int val,key; int size; }fhq[maxn]; int cnt,root; std::mt19937 rnd(233); 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 { ///如果当前节点的值是小于val ///那么这个当前节点的左子树也归到val ///我们把x=now相当于把这个点连接到分裂出来比这个值小的树 ///然后我们取递归分裂这个树的右子树 ///由于当前节点归到了小于的节点 但是这个接待那的右节点仍然需要重建 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; ///如果x的索引是大于y ///当前不满足二叉搜索树的形状,那么我们继续合并x的右子树 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; 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); printf("%d\n",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; } } printf("%d\n",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; printf("%d\n",fhq[now].val); root=merge(x,y); } inline void net(int val) { split(root,val,x,y); int now = y; while(fhq[now].l) now=fhq[now].l; printf("%d\n",fhq[now].val); root=merge(x,y); } int main(){ int t; int op; int val; cnt=0; scanf("%d",&t); while(t--){ scanf("%d%d",&op,&val); if (op==1){ ins(val); }else if (op==2){ del(val); }else if (op==3){ getrank(val); }else if (op==4){ getnum(val); }else if (op==5){ pre(val); }else { net(val); } } return 0; }
有不懂欢迎咨询
QQ:1326487164(添加时记得备注)