1. 程式人生 > >【bzoj3224】普通平衡樹——treap

【bzoj3224】普通平衡樹——treap

blog lib mes cas style tree upd treap ins

我的第一道treap題目,treap的模版題。

代碼是對著hzw的敲的,一邊敲一邊理解。。。

主要是熟悉一下treap的各種基本操作,詳細細節看代碼。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
using namespace std;
struct point
{
    int l,r,v,rnd,size,w;
}tree[100005];
int n,size=0,root=0,ans;
void update(int k)
{
    tree[k].size
=tree[tree[k].l].size+tree[tree[k].r].size+tree[k].w; } void rturn(int &t) { int k=tree[t].l; tree[t].l=tree[k].r; tree[k].r=t; tree[k].size=tree[t].size; update(t); t=k; } void lturn(int &t) { int k=tree[t].r; tree[t].r=tree[k].l; tree[k].l=t; tree[k].size
=tree[t].size; update(t); t=k; } void insert(int &k,int x) { if(k==0) { size++;k=size; tree[k].size=tree[k].w=1;tree[k].v=x;tree[k].rnd=rand(); return; } tree[k].size++; if(tree[k].v==x)tree[k].w++; else if(x>tree[k].v) { insert(tree[k].r,x);
if(tree[tree[k].r].rnd<tree[k].rnd)lturn(k); } else { insert(tree[k].l,x); if(tree[tree[k].l].rnd<tree[k].rnd)rturn(k); } } void del(int &k,int x) { if(k==0)return ; if(tree[k].v==x){ if(tree[k].w>1){ tree[k].w--;tree[k].size--;return; } if(tree[k].l*tree[k].r==0)k=tree[k].l+tree[k].r; else if(tree[tree[k].l].rnd<tree[tree[k].r].rnd)rturn(k),del(k,x); else lturn(k),del(k,x); } else if(x>tree[k].v) tree[k].size--,del(tree[k].r,x); else tree[k].size--,del(tree[k].l,x); } int get_rank(int k,int x) { if(k==0)return 0; if(tree[k].v==x)return tree[tree[k].l].size+1; else if(tree[k].v<x)return tree[tree[k].l].size+tree[k].w+get_rank(tree[k].r,x); else return get_rank(tree[k].l,x); } int get_x(int k,int x) { if(k==0)return 0; if(x<=tree[tree[k].l].size)return get_x(tree[k].l,x); else if(x>tree[tree[k].l].size+tree[k].w)return get_x(tree[k].r,x-tree[tree[k].l].size-tree[k].w); else return tree[k].v; } void get_big(int k,int x) { if(k==0)return; if(tree[k].v<x) { ans=k;get_big(tree[k].r,x); } else get_big(tree[k].l,x); } void get_small(int k,int x) { if(k==0)return ; if(tree[k].v>x) { ans=k;get_small(tree[k].l,x); } else get_small(tree[k].r,x); } int main() { scanf("%d",&n); int opt,x; for(int i=1;i<=n;i++) { scanf("%d %d",&opt,&x); switch(opt) { case 1:insert(root,x);break; case 2:del(root,x);break; case 3:printf("%d\n",get_rank(root,x));break; case 4:printf("%d\n",get_x(root,x));break; case 5:ans=0;get_big(root,x);printf("%d\n",tree[ans].v);break; case 6:ans=0;get_small(root,x);printf("%d\n",tree[ans].v);break; } } return 0; }

萬分感謝黃學長啊啊啊啊

【bzoj3224】普通平衡樹——treap