这是我干过最有勇气的一件事。
为什么我要看这玩意。。好懂难写的玩意
不过也算吧….每天抽空出来,终于把自己的SBT模板打出来了
查询什么的其实挺简单,
主要麻烦在修改和维护上了。
#include
#include
#include
using namespace std;
const int N=100100;int M;
struct ss{
int key[N],s[N],left[N],right[N];
int rt,nodecnt;
void clear(){
rt=0,nodecnt=0;
memset(key,0,sizeof(key));
memset(s,0,sizeof(s));
memset(left,0,sizeof(left));
memset(right,0,sizeof(right));
};
void z_x(int &p){//左旋
int k=right[p];
right[p]=left[k];left[k]=p;
s[k]=s[p];
s[p]=s[right[p]]+s[left[p]]+1;
p=k;
}void y_x(int &p){//右旋
int k=left[p];
left[p]=right[k];right[k]=p;
s[k]=s[p];
s[p]=s[right[p]]+s[left[p]]+1;
p=k;
}
//旋比较简单,不注释了。
void peace(int &p,bool flag){
if(!flag){//加到了左子树
if(s[left[left[p]]]>s[right[p]]) y_x(p);
else {//加到了左子树的右子树
if(s[right[left[p]]]>s[right[p]]){
z_x(left[p]);y_x(p);
}else return ;
}
}else{//反之
if(s[right[right[p]]]>s[left[p]])
z_x(p);
else{
if(s[left[right[p]]]>s[left[p]]){
y_x(right[p]);z_x(p);
}else return;
}
}
peace(left[p],false);
peace(right[p],true);
peace(p,true);
peace(p,false);
}//平衡...也比较简单,不说了。
void insert(int &p,int x){//加入一个值为x的数
if(!p){
p=++nodecnt;key[p]=x;s[p]=1;
return;
}s[p]++;
if(xelse insert(right[p],x);
peace(p,x>=key[p]);
}//插入一个数....也比找到合适的位置就好。
int del(int &p,int x){//删除一个值为x的数
s[p]--;int tmp;
if(x==key[p]||(xkey[p]&&!right[p])){
tmp=key[p];
if(!left[p]||!right[p])
p=left[p]+right[p];
else key[p]=del(left[p],key[p]+1);
return tmp;
}if(xelse tmp=del(right[p],x);
return tmp;
}
int rank(int &p,int x){//x的排名
if(!p) return 1;int tmp=0;
if(x<=key[p]) tmp=rank(left[p],x);
else tmp=s[left[p]]+1+rank(right[p],x);
return tmp;
}
int select(int &p,int x){//第x小的数
if(x==s[left[p]]+1) return key[p];
if(x<=s[left[p]]) return select(left[p],x);
else return select(right[p],x-1-s[left[p]]);
}
int pred(int &p,int x){//x的前驱
if(!p) return x;int tmp;
if(x<=key[p]) tmp=pred(left[p],x);
else{tmp=pred(right[p],x);if(tmp==x)tmp=key[p];}
return tmp;
}int succ(int &p,int x){//x的后驱
if(!p)return x;int tmp;
if(x>=key[p]) tmp=succ(right[p],x);
else{tmp=succ(left[p],x);if(tmp==x)tmp=key[p];}
return tmp;
}
}T;
int main(){
T.clear();scanf("%d",&M);
int &rt=T.rt=0;
while(M--){
int opt,x;scanf("%d%d",&opt,&x);
if(opt==1) T.insert(rt,x);
else if(opt==2) T.del(rt,x);
else if(opt==3) printf("%d\n",T.rank(rt,x));
else if(opt==4) printf("%d\n",T.select(rt,x));
else if(opt==5) printf("%d\n",T.pred(rt,x));
else if(opt==6) printf("%d\n",T.succ(rt,x));
}return 0;
}
删除操作注:
一直往下找,直到找到这个数,然后把这个数删了,
继续按顺序往下找,直到找到一个可以代替删掉的那个数位置的数,然后返回。
这玩意,,,GG,,我还是学别的内容吧。