我的第一道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; }
万分感谢黄学长啊啊啊啊