treap平衡树
- 格式:wps
- 大小:26.50 KB
- 文档页数:4
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define N 201000
int l[N],r[N],v[N],hr[N],s[N];
int n,root,m;
namespace TREAP
{
inline void l_rotate(int & x){
int y =r[x];
r[x] = l[x];
l[y] = x;
s[y] = s[x];
s[x] = s[l[x]] + s[r[x]] + 1;
x = y;
return;
}
inline void r_rotate(int & x){
int y = l[x];
l[x] = r[x];
r[y] = x;
s[y] = s[x];
s[x] = s[l[x]] + s[r[x]] + 1;
x = y;
return;
}
void insert(int & k,int & key){
if (k == 0){
v[++m] = key;
s[m] = 1;
hr[m] = rand();
k = m;
return;
}
s[k]++;
if (key <= v[k]){
insert(l[k],key);
if (hr[l[k]] > hr[k]){
r_rotate(k);
}
return;
}
if (key > v[k]){
insert(r[k],key);
if (hr[r[k]] > hr[k]) l_rotate(k);
return;
}
return;
}
int del(int & k,int key){
int ans;
s[k]--;
if (key == v[k] || !l[k] && key<=v[k] || r[k] == 0 && key > v[k]){
ans = v[k];
if (!l[k] || !r[k]){
k = l[k] + r[k];
return ans;
}
v[k] = del(l[k],key+1);
return ans;
}
if (key <= v[k]) return del(l[k],key);
if (key > v[k]) return del(r[k],key);
}
bool find(int & k,int &key){
if (k == 0) return 0;
if (key > v[k]) return find(r[k],key);
else return (v[k] == key || find(l[k],key));
}
int rank(int & t,int & key){
int ans;
if (t == 0) return 1;
if (key <= v[t]) return rank(l[t],key);
else return s[l[t]] + 1 + rank(r[t],key);
}
int sel(int & t,int k){
if (k == s[l[t]]+1) return v[t];
if (k<=s[l[t]]) return sel(l[t],k);
else return sel(r[t],k-1-s[l[t]]);
}
int pred(int & t,int & key){
if (t == 0) return key;
if (key <= v[t]) return pred(l[t],key);
else{
int ans = pred(r[t],key);
if (ans == key) ans = v[t];
return ans;
}
}
int succ(int &t,int & key){
if (t == 0) return key;
if (v[t]<=key) return succ(r[t],key);
else{
int ans = succ(l[t],key);
if (ans == key) ans = v[t];
return ans;
}
}
}
inline void order(){
int a,b;
scanf("%d%d",&a,&b);
switch(a){
case 1:TREAP::insert(root,b);break;
case 2:TREAP::del(root,b);break;
case 3:printf("%d\n",TREAP::find(root,b));break;
case 4:printf("%d\n",TREAP::rank(root,b));break;
case 5:printf("%d\n",TREAP::sel(root,b));break;
case 6:printf("%d\n",TREAP::pred(root,b));break;
case 7:printf("%d\n",TREAP::succ(root,b));break;
}
return;
}
int main(){
srand(unsigned(time(0)));
scanf("%d",&n);
m = 0;
while (n--){
order();
}
return 0;
}