//建树

 struct data{
 	int l,r,v,size,rnd,w;
 }tr[100005];
 

int n,size,root,ans;

void update(int k){
	tr[k].size=tr[tr[k].l].size+tr[tr[k].r].size+tr[k].w; 
} 

单旋

void rturn(int &k){
	int t=tr[k].l;tr[k].l=tr[t].r;tr[t].r=k;
	tr[t].size=tr[k].size;update(k);k=t;
}

void lturn(int &k){
   int t=tr[k].r;tr[k].r=tr[t].l;tr[t].l=k;
   tr[t].size=tr[k].size;update(k);k=t;
}

双旋

srand(19268075);

treap的插入:

void insert(int &k,int x){
	if (k==0){//插入到一个空节点 
		size++;k=size; 
		tr[k].size=tr[k].w=1;
		tr[k].v=x;tr[k].rnd=rand();
		return;
	}
	tr[k].size++;
	if (tr[k].v==x) tr[k].v++;
	else if (x>tr[k].v)
	{
		insert(tr[k].r,x);
		if (tr[tr[k].r].rnd<tr[k].rnd)lturn(k);
		
	 } 
	 else {
	 	insert(tr[k].l,x);
	 	if (tr[tr[k].l].rnd<tr[k].rnd) rturn(k); //维护堆性质 
	 }
}

treap的删除:
和普通的BST删除是一样:
如果sh值小于当前值,则递归至左儿子;大于则递归至右儿子
若当前节点数值的出现次数大于1,则减一(通常将一个权值缩掉)

void del(int &k,int x){
	if (k==0) return;
    if (tr[k])//此处有误 
    {
	if (tr[k].w>1)
	{
		tr[k].w--;tr[k].size--;return;
	}
	if (tr[k].l*tr[k].r==0) k=tr[k].l+tr[k].r;
	else if (tr[tr[k].l].rnd<tr[tr[k]].rnd)
	   rturn (k),del(k,x);
	else lturn(k),del(k,x);
   }
   else if (x>tr[k].v)
      tr[k].size--,del(tr[k].r,x);
   else tr[k].size--,del(tr[k].l,x); 
}