#include<bits/stdc++.h>
using namespace std;
template<typename T>
struct TreapNode{
TreapNode<T> *lp,*rp;
int r,sz,rep_cnt;
T v;
TreapNode(T v):v(v),sz(1),rep_cnt(1){
lp=rp=nullptr;
r=rand();
}
void upd_sz(){
sz=rep_cnt;
if(lp!=nullptr) sz+=lp->sz;
if(rp!=nullptr) sz+=rp->sz;
}
};
template<typename T>
class Treap{
typedef TreapNode<T> Node;
private:
void rotateL(Node *&p){
Node* t=p->rp;
p->rp=t->lp;
t->lp=p;
p->upd_sz();
t->upd_sz();
p=t;
}
void rotateR(Node *&p){
Node* t=p->lp;
p->lp=t->rp;
t->rp=p;
p->upd_sz();
t->upd_sz();
p=t;
}
void ins(T x,Node *&p){
if(p==nullptr){
p=new Node(x);
return;
}
if(x==p->v){
p->sz++;
p->rep_cnt++;
return;
}
if(x<p->v){
ins(x,p->lp);
if(p->r>p->lp->r){
rotateR(p);
}
p->upd_sz();
return;
}
if(x>p->v){
ins(x,p->rp);
if(p->r>p->rp->r){
rotateL(p);
}
p->upd_sz();
return;
}
}
void del(T x,Node *&p){
if(p->v==x){
if(p->rep_cnt>1){
p->rep_cnt--;
p->sz--;
return;
}
if(!p->lp||!p->rp){
Node* t=p;
if(!p->lp){
p=p->rp;
}
else{
p=p->lp;
}
delete t;
}
else{
if(p->lp->r<p->rp->r){
rotateR(p);
del(x,p->rp);
p->upd_sz();
}
else{
rotateL(p);
del(x,p->lp);
p->upd_sz();
}
}
}
else if(x<p->v){
del(x,p->lp);
p->upd_sz();
}
else{
del(x,p->rp);
p->upd_sz();
}
}
public:
Node* root=nullptr;
void insert(T x){
if(root==nullptr){
root=new Node(x);
return;
}
ins(x,root);
}
void erase(T x){
del(x,root);
}
Treap():root(nullptr){
}
int query_rank(T x,Node* p){
if(p==nullptr){
return 1;
}
if(p->v==x){
return (p->lp==nullptr?0:p->lp->sz)+1;
}
else if(x<p->v){
return query_rank(x,p->lp);
}
else{
return (p->lp==nullptr?0:p->lp->sz)+1+query_rank(x,p->rp);
}
}
T query_value(int r,Node* p){
if(p==nullptr){
return T();
}
int lr=(p->lp==nullptr?0:p->lp->sz)+1;
if(lr==r){
return p->v;
}
if(r<lr){
return query_value(r,p->lp);
}
else{
return query_value(r-lr,p->rp);
}
}
Node* find_front(T x,Node* p){
if(p==nullptr){
return nullptr;
}
if(x<=p->v){
return find_front(x,p->lp);
}
else{
Node* t=find_front(x,p->rp);
if(t==nullptr){
return p;
}
return ((p->v)>=(t->v)?p:t);
}
}
Node* find_back(T x,Node* p){
if(p==nullptr){
return nullptr;
}
if(x>=p->v){
return find_back(x,p->rp);
}
else{
Node* t=find_back(x,p->lp);
if(t==nullptr){
return p;
}
return ((p->v)<=(t->v)?p:t);
}
}
};
int main(){
Treap<int> tree;
int T;
scanf("%d",&T);
while(T--){
int op,x;
scanf("%d %d",&op,&x);
if(op==2){
tree.erase(x);
}
if(op==3){
printf("%d\n",tree.query_rank(x,tree.root));
}
if(op==4){
printf("%d\n",tree.query_value(x,tree.root));
}
if(op==5){
auto p=tree.find_front(x,tree.root);
printf("%d\n",(p==nullptr?-2147483647:p->v));
}
if(op==6){
auto p=tree.find_back(x,tree.root);
printf("%d\n",(p==nullptr?2147483647:p->v));
}
if(op==1){
tree.insert(x);
}
}
return 0;
}
感觉是维护的 upd_sz() 错了,但是没找到在哪里少或者多更新了。
求调 qwq。