order_statistic_tree
insert,erase,find,cnt,order,lower_bound,upper_bound,miman,ika
が可能
class trp{
const long long INF = 1e18;
struct node{
int key;
int priority;
int siz;
node* left;
node* right;
node(int k,int p){
key = k;
priority = p;
siz = 1;
left = nullptr;
right = nullptr;
}
};
node* root;
bool find(node* t,int x){
if(t == nullptr)return false;
if(t -> key == x)return true;
if(x < t->key)return find(t->left,x);
else return find(t->right,x);
}
node* merge(node* l,node* r){
if(l == nullptr)return r;
if(r == nullptr)return l;
if(l->priority > r->priority){
l-> right = merge(l->right,r);
update(l);
return l;
}
else{
r->left = merge(l,r->left);
update(r);
return r;
}
}
pair<node*,node*> split(node* t,int x){
if(t==nullptr)return {nullptr,nullptr};
if(x <= t->key){
pair<node*,node*> p = split(t->left,x);
t -> left = p.second;
update(t);
return {p.first,t};
}
else{
pair<node*,node*> p = split(t->right,x);
t -> right = p.first;
update(t);
return {t,p.second};
}
}
int size(node* t){
if(t == nullptr)return 0;
else return t -> siz;
}
void update(node* t){
if(t == nullptr)return;
t -> siz = 1 + size(t->left)+size(t->right);
}
int cnt(node* t,int k){
if(t == nullptr)return -INF;
int lsiz = size(t->left);
if(lsiz > k){
return cnt(t -> left,k);
}
else if(k==lsiz){
return t->key;
}
else{
return cnt(t -> right,k - lsiz - 1);
}
}
int order(node* t,int x){
if(t == nullptr)return 0;
if(x <= t->key){
return order(t -> left,x);
}
else{
return size(t -> left) + 1 + order(t->right,x);
}
}
node* lower_bound(node* t, int x){
if(t == nullptr) return nullptr;
if(t->key < x){
return lower_bound(t->right, x);
}
else{
node* res = lower_bound(t->left, x);
if(res != nullptr) return res;
else return t;
}
}
node* upper_bound(node* t, int x){
if(t == nullptr) return nullptr;
if(t->key <= x){
return upper_bound(t->right, x);
}
else{
node* res = upper_bound(t->left, x);
if(res != nullptr) return res;
else return t;
}
}
node* ika(node* t,int x){
if(t==nullptr)return nullptr;
if(t -> key > x){
return ika(t->left,x);
}
else{
node*res = ika(t->right,x);
if(res != nullptr)return res;
else return t;
}
}
public :
trp(){
root = nullptr;
}
bool find(int x){
return find(root,x);
}
void insert(int x){
if(find(x))return;
pair<node*,node*> p = split(root,x);
node* r = p.second;
node* l = p.first;
node* n = new node(x,rand());
root = merge(merge(l,n),r);
}
void erase(int x){
if(!find(x))return ;
pair<node*,node*> a = split(root,x);
pair<node*,node*> b = split(a.second,x+1);
root = merge(a.first,b.second);
}
int cnt(int k){
return cnt(root,k);
}
int order(int x){
return order(root,x);
}
int lower_bound(int x){
node* res = lower_bound(root, x);
if(res == nullptr) return -INF;
return res->key;
}
int upper_bound(int x){
node* res = upper_bound(root, x);
if(res == nullptr) return -INF;
return res->key;
}
int miman(int x){
int k = order(x) -1;
if(k < 0)return -INF;
return cnt(k);
}
int ika(int x){
node* k = ika(root,x);
if(k == nullptr)return -INF;
else return k->key;
}
};