我的第一道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 ",get_rank(root,x));break; case 4:printf("%d ",get_x(root,x));break; case 5:ans=0;get_big(root,x);printf("%d ",tree[ans].v);break; case 6:ans=0;get_small(root,x);printf("%d ",tree[ans].v);break; } } return 0; }
万分感谢黄学长啊啊啊啊