BZOJ 3224 普通平衡树
Posted zhangenming
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ 3224 普通平衡树相关的知识,希望对你有一定的参考价值。
3224: Tyvj 1728 普通平衡树
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 16841 Solved: 7319
[Submit][Status][Discuss]
Description
您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:
1. 插入x数
2. 删除x数(若有多个相同的数,因只删除一个)
3. 查询x数的排名(若有多个相同的数,因输出最小的排名)
4. 查询排名为x的数
5. 求x的前驱(前驱定义为小于x,且最大的数)
6. 求x的后继(后继定义为大于x,且最小的数)
Input
第一行为n,表示操作的个数,下面n行每行有两个数opt和x,opt表示操作的序号(1<=opt<=6)
Output
对于操作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
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
84185
492737
HINT
1.n的数据范围:n<=100000
2.每个数的数据范围:[-2e9,2e9]
Source
很裸的平衡树Treep,Splay都能写
1 #include <bits/stdc++.h> 2 using namespace std; 3 char buf[1<<15],*fs,*ft; 4 inline char getc(){return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:*fs++;} 5 inline int read(){ 6 int x=0,f=1; char ch=getc(); 7 while(!isdigit(ch)) {if(ch==‘-‘) f=-1; ch=getc();} 8 while(isdigit(ch)) {x=x*10+ch-‘0‘; ch=getc();} 9 return x*f; 10 } 11 void put(int x){ 12 if(x==0){ 13 putchar(‘0‘); 14 putchar(‘\n‘); 15 return; 16 } 17 if(x<0){ 18 putchar(‘-‘); 19 x=-x; 20 } 21 int num=0;char ch[16]; 22 while(x) ch[++num]=x%10+‘0‘,x/=10; 23 while(num) putchar(ch[num--]); 24 putchar(‘\n‘); 25 } 26 const int MAXN=1e6+10; 27 namespace zhangenming{ 28 struct node{ 29 int weight,sum,have,v;//weight表示节点的含有个数,sum表示所有子节点的和,have表示优先级,v表示节点的值 30 int leftt,rightt; 31 }T[MAXN]; 32 int n,tol=0,ans=0,root=0; 33 inline void update(int root){ 34 T[root].sum=T[T[root].leftt].sum+T[T[root].rightt].sum+T[root].weight; 35 } 36 inline void left_rote(int &now){ 37 int tmp=T[now].rightt; 38 T[tmp].sum=T[now].sum; 39 T[now].rightt=T[tmp].leftt; 40 T[tmp].leftt=now; 41 update(now); 42 now=tmp; 43 } 44 inline void right_rote(int &now){ 45 int tmp=T[now].leftt; 46 T[tmp].sum=T[now].sum; 47 T[now].leftt=T[tmp].rightt; 48 T[tmp].rightt=now; 49 update(now); 50 now=tmp; 51 } 52 inline void insert(int x,int &root){ 53 if(root==0){ 54 tol++; 55 root=tol; 56 T[root].v=x; 57 T[root].weight=T[root].sum=1; 58 T[root].have=rand(); 59 return ; 60 } 61 T[root].sum++; 62 if(T[root].v==x) {T[root].weight++;} 63 else{ 64 if(x<T[root].v){ 65 insert(x,T[root].leftt); 66 if(T[T[root].leftt].have>T[root].have) right_rote(root); 67 } 68 else{ 69 insert(x,T[root].rightt); 70 if(T[T[root].rightt].have>T[root].have) left_rote(root); 71 } 72 } 73 } 74 inline void delte(int x,int &root){ 75 if(root==0) return ; 76 if(x==T[root].v){ 77 if(T[root].weight>1){ 78 T[root].weight--;T[root].sum--;return ; 79 } 80 if(T[root].leftt*T[root].rightt==0){ 81 root=T[root].leftt+T[root].rightt; 82 } 83 else{ 84 if(T[T[root].leftt].have<T[T[root].rightt].have){ 85 right_rote(root);delte(x,root); 86 } 87 else{ 88 left_rote(root);delte(x,root); 89 } 90 } 91 } 92 else{ 93 if(T[root].v>x) {T[root].sum--;delte(x,T[root].leftt);} 94 else {T[root].sum--;delte(x,T[root].rightt);} 95 } 96 } 97 inline int getrank(int x,int root){ 98 if(root==0) return 0; 99 if(T[root].v>x) return getrank(x,T[root].leftt); 100 else{ 101 if(T[root].v<x) return T[T[root].leftt].sum+T[root].weight+getrank(x,T[root].rightt); 102 else return T[T[root].leftt].sum+1; 103 } 104 } 105 inline int getnum(int x,int root){ 106 if(root==0) return 0; 107 if(x>T[root].weight+T[T[root].leftt].sum){ 108 return getnum(x-T[root].weight-T[T[root].leftt].sum,T[root].rightt); 109 } 110 else{ 111 if(x>T[T[root].leftt].sum){ 112 return T[root].v; 113 } 114 else{ 115 return getnum(x,T[root].leftt); 116 } 117 } 118 } 119 inline void getpre(int x,int root){ 120 if(root==0) return; 121 if(T[root].v<x){ 122 ans=T[root].v; 123 getpre(x,T[root].rightt); 124 } 125 else getpre(x,T[root].leftt); 126 } 127 inline void getnext(int x,int root){ 128 if(root==0) return; 129 if(T[root].v>x){ 130 ans=T[root].v; 131 getnext(x,T[root].leftt); 132 } 133 else getnext(x,T[root].rightt); 134 } 135 void init(){ 136 n=read(); 137 for(int i=1;i<=n;i++){ 138 int id=read(); 139 int xx=read(); 140 if(id==1) insert(xx,root); 141 if(id==2) delte(xx,root); 142 if(id==3) put(getrank(xx,root)); 143 if(id==4) put(getnum(xx,root)); 144 if(id==5) {getpre(xx,root);put(ans);} 145 if(id==6) {getnext(xx,root);put(ans);} 146 } 147 } 148 } 149 int main(){ 150 //freopen("a.in","r",stdin); 151 //freopen("a.out","w",stdout); 152 using namespace zhangenming; 153 init(); 154 return 0; 155 }
以上是关于BZOJ 3224 普通平衡树的主要内容,如果未能解决你的问题,请参考以下文章
bzoj3224: Tyvj 1728 普通平衡树(spaly)