[BZOJ3224]普通平衡樹
阿新 • • 發佈:2017-05-29
hint esp treap tput center remove border 實現 out
題目描述 Description |
您需要寫一種數據結構(可參考題目標題),來維護一些數,其中需要提供以下操作: 1. 插入x數 2. 刪除x數(若有多個相同的數,因只刪除一個) 3. 查詢x數的排名(若有多個相同的數,因輸出最小的排名) 4. 查詢排名為x的數 5. 求x的前驅(前驅定義為小於x,且最大的數) 6. 求x的後繼(後繼定義為大於x,且最小的數) |
輸入描述 Input Description |
第一行為n,表示操作的個數,下面n行每行有兩個數opt和x,opt表示操作的序號(1<=opt<=6) |
輸出描述 Output Description |
對於操作3,4,5,6每行輸出一個數,表示對應答案 |
樣例輸入 Sample Input |
10 1 106465 4 1 1 317721 1 460929 1 644985 1 84185 1 89851 6 81968 1 492737 5 493598 |
樣例輸出 Sample Output |
106465 84185 492737 |
數據範圍及提示 Data Size & Hint |
1.n的數據範圍:n<=100000
2.每個數的數據範圍:[-2e9,2e9] |
最裸的平衡樹題。用treap來實現,由於是可重復的,我這裏默認如果鍵值相同就往左子樹插,然後一些經典操作例如什麽找前驅後繼,排名什麽的上面都寫了,希望當作以後的模板。
#include<iostream> #include<algorithm> #include<cstdio> #include<queue> #include<cmath> #include<cstring> #include<ctime> using namespace std; typedef long longView CodeLL; #define mem(a,b) memset(a,b,sizeof(a)) inline int read() { int x=0,f=1;char c=getchar(); while(!isdigit(c)){if(c==‘-‘)f=-1;c=getchar();} while(isdigit(c)){x=x*10+c-‘0‘;c=getchar();} return x*f; } const int maxn=100010,oo=2147483647; struct node { int val,rnd; int cmp(int v)const { if(val==v)return -1; return v<val ? 0 : 1; } }ns[maxn]; int tot,rt,ch[2][maxn],size[maxn]; int New(int v) { int o=++tot;ns[o].val=v;ns[o].rnd=rand(); ch[0][o]=ch[1][o]=0;return o; } void del(int o){ns[o].val=ns[o].rnd=ch[0][o]=ch[1][o]=size[o]=0;o=0;} void maintain(int o) { if(!o)return; size[o]=1; if(ch[0][o])size[o]+=size[ch[0][o]]; if(ch[1][o])size[o]+=size[ch[1][o]]; } void rotate(int &o,int d) { int k=ch[d^1][o];ch[d^1][o]=ch[d][k];ch[d][k]=o; maintain(o);o=k;return maintain(o); } void insert(int &o,int v) { if(!o){o=New(v);return maintain(o);} int d= v<=ns[o].val ? 0 : 1; insert(ch[d][o],v); if(ns[ch[d][o]].rnd>ns[o].rnd)rotate(o,d^1); return maintain(o); } void remove(int &o,int v) { if(!o)return; int d=ns[o].cmp(v); if(d==-1) { int t=o; if(ch[0][o] && ch[1][o]) { int d2= ns[ch[0][o]].rnd>ns[ch[1][o]].rnd ? 1 : 0; rotate(o,d2);remove(ch[d2][o],v); } else if(!ch[0][o])o=ch[1][o]; else o=ch[0][o]; del(t); } else remove(ch[d][o],v); return maintain(o); } int kth(int o,int k) { if(!o || k<0 || k>size[o])return 0; int s=size[ch[0][o]]; if(k==s+1)return ns[o].val; else if(k<=s)return kth(ch[0][o],k); else return kth(ch[1][o],k-s-1); } int rank(int o,int v) { if(!o)return 0; if(v>ns[o].val)return size[ch[0][o]]+1+rank(ch[1][o],v); return rank(ch[0][o],v); } int lower(int o,int v) { if(!o)return -oo; if(ns[o].val<v)return max(ns[o].val,lower(ch[1][o],v)); else return lower(ch[0][o],v); } int upper(int o,int v) { if(!o)return oo; if(ns[o].val>v)return min(ns[o].val,upper(ch[0][o],v)); else return upper(ch[1][o],v); } int n,tp,x; int main() { n=read(); while(n--) { tp=read();x=read(); if(tp==1)insert(rt,x); else if(tp==2)remove(rt,x); else if(tp==3)printf("%d\n",rank(rt,x)+1); else if(tp==4)printf("%d\n",kth(rt,x)); else if(tp==5)printf("%d\n",lower(rt,x)); else if(tp==6)printf("%d\n",upper(rt,x)); } return 0; }
[BZOJ3224]普通平衡樹