BZOJ3224: Tyvj 1728 普通平衡树
题目:http://www.lydsy.com/JudgeOnline/problem.php?id=3224
题解:
复习了一下treap,也算是一个完整的模板了吧。
代码:
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<cmath> 5 #include<algorithm> 6 #include<string> 7 #include<set> 8 #include<map> 9 #include<vector> 10 #include<iostream> 11 #include<queue> 12 #define for0(i,n) for(int i=0;i<=n;i++) 13 #define for1(i,n) for(int i=1;i<=n;i++) 14 #define for2(i,x,y) for(int i=x;i<=y;i++) 15 #define for3(i,y,x) for(int i=y;i>=x;i--) 16 #define maxn (3000000+5) 17 using namespace std; 18 inline int read() 19 { 20 int x=0,f=1;char ch=getchar(); 21 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 22 while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();} 23 return x*f; 24 } 25 int tot,rt,s[maxn],l[maxn],r[maxn],v[maxn],w[maxn],h[maxn]; 26 inline void pushup(int k) 27 { 28 s[k]=s[l[k]]+s[r[k]]+w[k]; 29 } 30 inline void lturn(int &k) 31 { 32 int t=r[k];r[k]=l[t];l[t]=k;s[t]=s[k];pushup(k);k=t; 33 } 34 inline void rturn(int &k) 35 { 36 int t=l[k];l[k]=r[t];r[t]=k;s[t]=s[k];pushup(k);k=t; 37 } 38 inline void ins(int &k,int x) 39 { 40 if(!k){k=++tot;s[k]=w[k]=1;v[k]=x;h[k]=rand();return;} 41 s[k]++; 42 if(x==v[k])w[k]++; 43 else if(x<v[k]){ins(l[k],x);if(h[l[k]]>h[k])rturn(k);} 44 else {ins(r[k],x);if(h[r[k]]>h[k])lturn(k);} 45 } 46 inline void del(int &k,int x) 47 { 48 if(v[k]==x) 49 { 50 if(w[k]>1)w[k]--,s[k]--; 51 else if(l[k]*r[k]==0)k=l[k]+r[k]; 52 else if(h[l[k]]>h[r[k]]){rturn(k);del(k,x);} 53 else {lturn(k);del(k,x);} 54 return; 55 } 56 s[k]--; 57 if(x<v[k])del(l[k],x);else del(r[k],x); 58 } 59 inline int find(int k,int x) 60 { 61 if(s[l[k]]<x&&s[l[k]]+w[k]>=x)return v[k]; 62 else if(s[l[k]]>=x)return find(l[k],x); 63 else return find(r[k],x-s[l[k]]-w[k]); 64 } 65 inline int rank(int k,int x) 66 { 67 if(!k)return 0; 68 if(v[k]==x)return s[l[k]]; 69 else if(x<v[k])return rank(l[k],x); 70 else return s[l[k]]+w[k]+rank(r[k],x); 71 } 72 inline int prev(int k,int x) 73 { 74 if(!k)return x; 75 if(x<=v[k])return prev(l[k],x); 76 else {int t=prev(r[k],x);return t==x?v[k]:t;} 77 } 78 inline int next(int k,int x) 79 { 80 if(!k)return x; 81 if(v[k]<=x)return next(r[k],x); 82 else {int t=next(l[k],x);return t==x?v[k]:t;} 83 } 84 int main() 85 { 86 freopen("input.txt","r",stdin); 87 freopen("output.txt","w",stdout); 88 int m=read(); 89 while(m--) 90 { 91 int ch=read(),x=read(); 92 if(ch==1)ins(rt,x); 93 else if(ch==2)del(rt,x); 94 else if(ch==3)printf("%d\n",rank(rt,x)+1); 95 else if(ch==4)printf("%d\n",find(rt,x)); 96 else if(ch==5)printf("%d\n",prev(rt,x)); 97 else printf("%d\n",next(rt,x)); 98 } 99 return 0; 100 }