标签: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