标签:size rand merge text 素数 c++ 大小 name style
学了一下,好像明白了(背下来了)
不想写main函数了
PS:这个比treap好写(私以为)
#include<bits/stdc++.h> using namespace std; int tot,root; struct treap{ int v,ch[2],rnd; }t[N]; void split(int now,int k,int &x,int &y){//将now分为x,y两棵子树(可以为空) if(!now){ x=y=0; return; } if(t[now].val<=k) x=now,split(t[now].ch[1],k,t[now].ch[1],y);//now即为左子树根,递归处理右子树,此时x的左子树为now分裂出的小于等于k的子树的左子树,还要找到其右子树,即为now右儿子分裂出的小于子树 else //即可解释上行的函数调用,修改了now的右子树 y=now,spilt(t[now].ch[0],k,x,t[now].ch[0]); } int merge(int x,int y){ if(!x||!y)return x+y; update(x),update(y); if(t[x].rnd<t[y].rnd){ t[x].ch[1]=merge(t[x].ch[1],y); update(x); return x; } else { t[y].ch[0]=merge(x,t[y].ch[0]); update(y); return y; } } int neww(int v){ t[++tot].size=1; t[tot].val=v; t[tot].rnd=rand(); return tot; } int kth(int now,int k)// 查询排名 { while(1) { if(k<=t[t[now].ch[0]].size) now=t[now].ch[0];// 在左子树中,且数量小于左子树的大小,迭代寻找 else if(k==t[t[now].ch[0]].size+1) return now;// 找到了 else k-=t[t[now].ch[0]].size+1,now=t[now].ch[1];// 去右子树找 } } /*插入v split(root,v,x,y); root=merge(merge(x,neww(v)),y); */ /* split(root,v,a,b); split(a,v-1,a,d); d=merge(t[d].ch[0],t[d].ch[1]);这样写是因为可以不维护size(指元素数量) root=merge(merge(a,d),b); */ /*查询rank split(root,a-1,x,y); printf("%d\n",t[x].size+1); root=merge(x,y); */ /*查值 printf("%d\n",t[kth(root,a)].val); */ /*找前驱 split(root,a-1,x,y); printf("%d\n",t[kth(x,siz[x])].val); root=merge(x,y); */ /*找后继 split(root,a,x,y); printf("%d\n",t[kth(y,1)].val); root=merge(x,y); */ int main(){ return 0; }
标签:size rand merge text 素数 c++ 大小 name style
原文地址:https://www.cnblogs.com/Hikigaya/p/10600975.html