线段树打平衡树
你们看看你们配嘛
普通平衡树
线段树永远的神
维护一个权值线段树
不用离散化,数据范围够小
插入就直接插入
删除就插入-1
查找序号就查找他前面所有值的siz(大小)
找前趋就先把这个数的序号找出来,然后找前面的数
找后趋有点麻烦,需要把这个数一共有几个找到,然后用这个数的序号加上他,再寻找
就这样
看代码
#include<bits/stdc++.h>
using namespace std;
#define re register int
#define lc x<<1
#define rc x<<1|1
const int N=100005;
int n;
int siz[N*805];
void update(int x,int l,int r,int pos,int k){
//插入权值
if(l==r){
siz[x]+=k;
return ;
}
int mid=l+r>>1;
if(pos<=mid)update(lc,l,mid,pos,k);
else update(rc,mid+1,r,pos,k);
siz[x]=siz[lc]+siz[rc];
}
int queryx(int x,int l,int r,int pos,int &sum){
//找此权值所在的序号,sum是这个权值一共有几个
if(l==r){
sum=siz[x];
return 1;
}
int mid=l+r>>1;
if(pos<=mid)return queryx(lc,l,mid,pos,sum);
else return siz[lc]+queryx(rc,mid+1,r,pos,sum);
}
int queryp(int x,int l,int r,int xu){
//找序号为xu的数
if(l==r)return l;
int mid=l+r>>1;
if(siz[lc]>=xu)return queryp(lc,l,mid,xu);
else return queryp(rc,mid+1,r,xu-siz[lc]);
}
int main(){
scanf("%d",&n);
int u;
int typ[N],x[N],maxn=0,minn=1;
for(re i=1;i<=n;i++){
scanf("%d%d",&typ[i],&x[i]);
if(typ[i]==4)continue;
maxn=max(maxn,x[i]);
minn=min(minn,x[i]);
}
for(re i=1;i<=n;i++){
if(typ[i]==1)update(1,minn,maxn,x[i],1);
if(typ[i]==2)update(1,minn,maxn,x[i],-1);
if(typ[i]==3)printf("%d\n",queryx(1,minn,maxn,x[i],u));
if(typ[i]==4)printf("%d\n",queryp(1,minn,maxn,x[i]));
if(typ[i]==5){
int o=queryx(1,minn,maxn,x[i],u);
printf("%d\n",queryp(1,minn,maxn,o-1));
}
if(typ[i]==6){
int o=queryx(1,minn,maxn,x[i],u);
printf("%d\n",queryp(1,minn,maxn,o+u));
}
}
}