split_rk 函数会导致RE 求大佬查看原因
#include<bits/stdc++.h>
using namespace std;
struct NODE{
int val,size,rank,cnt;
NODE* son[2];
NODE(int x):val(x){
rank=rand();
cnt=size=1;
son[0]=son[1]=nullptr;
}
inline void upd_size(){
size=cnt;
if(son[0]!=nullptr)
size+=son[0]->size;
if(son[1]!=nullptr)
size+=son[1]->size;
}
};
pair<NODE*,NODE*> split_val(int val,NODE* cur){
if(cur==nullptr)
return {nullptr,nullptr};
if(cur->val<val){
auto temp=split_val(val,cur->son[1]);
cur->son[1]=temp.first;
cur->upd_size();
return {cur,temp.second};
}else{
auto temp=split_val(val,cur->son[0]);
cur->son[0]=temp.second;
cur->upd_size();
return {temp.first,cur};
}
}
tuple<NODE*,NODE*,NODE*> split_rk(int rk,NODE* cur){
if(cur==nullptr)return{nullptr,nullptr,nullptr};
int ls_size=cur->son[0]==nullptr?0:cur->son[0]->size;
if(rk<=ls_size){
NODE *ls,*mid,*rs;
tie(ls,mid,rs)=split_rk(rk,cur->son[0]);
cur->son[0]=rs;
cur->upd_size();
return {ls,mid,cur};
}else if(rk<=ls_size+cur->cnt){
NODE *ls=cur->son[0],*rs=cur->son[1];
cur->son[0]=cur->son[1]=nullptr;
return {ls,cur,rs};
}else{
NODE *ls,*mid,*rs;
tie(ls,mid,rs)=split_rk(rk-ls_size-cur->size,cur->son[1]);
cur->son[1]=ls;
cur->upd_size();
return {cur,mid,rs};
}
}
NODE* merge(NODE* a,NODE* b){
if(a==nullptr)
return b;
if(b==nullptr)
return a;
if(a->rank<b->rank){
a->son[1]=merge(a->son[1],b);
a->upd_size();
return a;
}else{
b->son[0]=merge(a,b->son[0]);
b->upd_size();
return b;
}
}
NODE* insert(int x,NODE* cur){
auto temp1=split_val(x,cur);
auto temp2=split_val(x+1,temp1.second);
if(temp2.first!=nullptr){
temp2.first->cnt++;
return merge(merge(temp1.first,temp2.first),temp2.second);
}
return merge(merge(temp1.first,new NODE(x)),temp2.second);
}
NODE* del(int x,NODE* cur){
auto temp1=split_val(x,cur);
auto temp2=split_val(x+1,temp1.second);
if(temp2.first==nullptr)
return merge(temp1.first,temp2.second);
temp2.first->cnt--;
if(!temp2.first->cnt)
return merge(temp1.first,temp2.second);
return merge(merge(temp1.first,temp2.first),temp2.second);
}
int query_rk(int x,NODE* cur){
auto temp1=split_val(x,cur);
int res=temp1.first->size;
cur=merge(temp1.first,temp1.second);
return res;
}
int query_val(int rank,NODE* cur){
NODE *ls,*mid,*rs;
tie(ls,mid,rs)=split_rk(rank+1,cur);
int res=mid->val;
cur=merge(merge(ls,mid),rs);
return res;
}
int pre_num(int x,NODE* cur){
auto temp=split_val(x,cur);
NODE *temp2=temp.first;
while(temp2->son[1]!=nullptr)
temp2=temp2->son[1];
int res=temp2->val;
cur=merge(temp.first,temp.second);
return res;
}
int nex_num(int x,NODE* cur){
auto temp=split_val(x+1,cur);
NODE *temp1=temp.second;
while(temp1->son[0]!=nullptr)
temp1=temp1->son[0];
int res=temp1->val;
cur=merge(temp.first,temp.second);
return res;
}
int n,opt,x;
int main(){
NODE *ROOT=new NODE(INT_MIN);
ROOT=merge(ROOT,new NODE(INT_MAX));
cin>>n;
while(n--){
scanf("%d%d",&opt,&x);
switch(opt){
case 1:
ROOT=insert(x,ROOT);
break;
case 2:
ROOT=del(x,ROOT);
break;
case 3:
printf("%d\n",query_rk(x,ROOT));
break;
case 4:
printf("%d\n",query_val(x,ROOT));
break;
case 5:
printf("%d\n",pre_num(x,ROOT));
break;
case 6:
printf("%d\n",nex_num(x,ROOT));
}
}
}