BZOJ 3224 普通平衡树

Posted zhangenming

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ 3224 普通平衡树相关的知识,希望对你有一定的参考价值。

3224: Tyvj 1728 普通平衡树

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 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

Sample Output

106465
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普通平衡树——treap

bzoj3224: Tyvj 1728 普通平衡树(spaly)

bzoj 3224: Tyvj 1728 普通平衡树 && loj 104 普通平衡树 (splay树)

BZOJ3224: Tyvj 1728 普通平衡树

BZOJ 3224 普通平衡树

bzoj3224: Tyvj 1728 普通平衡树