社区讨论
How Splay
学术版参与者 1已保存回复 0
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @mk7md08z
- 此快照首次捕获于
- 2026/01/10 09:21 上个月
- 此快照最后确认于
- 2026/01/12 13:30 上个月
CPP
void insert(ll sum){
if(root==NULL){
root=new Splay_Node(sum);
return;
}
Splay_Node* lrt=lower_bound(sum);
if(lrt!=NULL&&lrt->sum==sum){
lrt->self_siz++;
update(lrt);
return;
}
Splay_Node* rrt=upper_bound(sum);
splay(lrt,root);
splay(rrt,lrt);
Splay_Node* newnode=new Splay_Node(sum);
rrt->ls=newnode;
newnode->fa=rrt;
update(rrt);
update(lrt);
}
当插入一下特殊情况时,会RE。
如插入序列最大值时
题目为【模版】普通平衡树
完整代码:
CPPstruct Splay{
struct Splay_Node{
ll sum;
int siz, self_siz;
Splay_Node* ls;
Splay_Node* rs;
Splay_Node* fa;
Splay_Node(ll _sum) : siz(1), self_siz(1), ls(NULL), rs(NULL), fa(NULL) { sum=_sum; }
};
Splay_Node* root;
Splay() : root(NULL) {}
void update(Splay_Node* &rt){
if(rt!=NULL){
rt->siz=rt->self_siz;
if(rt->ls!=NULL) rt->siz+=rt->ls->siz;
if(rt->rs!=NULL) rt->siz+=rt->rs->siz;
}
}
int get(Splay_Node* rt){
return rt->fa->rs==rt;
}
void rotate(Splay_Node* rt){
Splay_Node* f=rt->fa;
Splay_Node* g=f->fa;
if(get(rt)){
f->rs=rt->ls;
if(f->rs!=NULL) f->rs->fa=f;
rt->ls=f;
}else{
f->ls=rt->rs;
if(f->ls!=NULL) f->ls->fa=f;
rt->rs=f;
}
f->fa=rt;
rt->fa=g;
if(g!=NULL){
if(g->rs==f) g->rs=rt;
else g->ls=rt;
}
update(f);
update(rt);
}
void splay(Splay_Node* rt,Splay_Node* to){
if(rt==NULL) return;
if(to==NULL) root=rt;
while(1){
Splay_Node* f=rt->fa;
Splay_Node* g=f->fa;
if(f==to) break;
if(g!=to){
if(get(rt)==get(f)) rotate(f);
else rotate(rt);
}
rotate(rt);
}
update(rt);
}
Splay_Node* build(int dl,int dr,Splay_Node* fa,ll *arr){//You need to ensure that the array is sorted.
if(dr>dl) return NULL;
int mid=(dl+dr)>>1;
Splay_Node* newnode=new Splay_Node(arr[mid]);
newnode->fa=fa;
newnode->ls=build(dl,mid-1,newnode,arr);
newnode->rs=build(mid+1,dr,newnode,arr);
update(newnode);
return newnode;
}
void clear(Splay_Node* rt){
if(rt==NULL) return;
clear(rt->ls);
clear(rt->rs);
delete rt;
}
Splay_Node* merge(Splay_Node* rt1,Splay_Node* rt2){
if(rt1==NULL&&rt2==NULL) return NULL;
if(rt1==NULL) return rt2;
if(rt2==NULL) return rt1;
splay(rt2,root);
rt2->ls=rt1;
rt1->fa=rt2;
update(rt2);
return rt2;
}
Splay_Node* kth(int k){
Splay_Node* nw=root;
while(1){
if(nw==NULL) return NULL;
if(nw->ls!=NULL&&k<=nw->ls->siz) nw=nw->ls;
else{
int tp=((nw->ls!=NULL)?(nw->ls->siz):(0))+nw->self_siz;
if(k<=tp) return nw;
k-=tp,nw=nw->rs;
}
}
}
int rk(ll sum){
Splay_Node* nw=root;
int ans=1;
while(1){
if(nw==NULL) return -1;
if(sum<nw->sum) nw=nw->ls;
else{
ans+=((nw->ls!=NULL)?(nw->ls->siz):(0));
if(sum==nw->sum){
splay(nw,root);
return ans;
}
ans+=nw->self_siz;
nw=nw->rs;
}
}
}
Splay_Node* lower_bound(ll sum){
Splay_Node* nw=root;
Splay_Node* ans=NULL;
while(nw!=NULL){
if(sum<=nw->sum) ans=nw,nw=nw->ls;
else nw=nw->rs;
}
if(ans!=NULL) splay(ans,root);
return ans;
}
Splay_Node* upper_bound(ll sum){
Splay_Node* nw=root;
Splay_Node* ans=NULL;
while(nw!=NULL){
if(sum<nw->sum) ans=nw,nw=nw->ls;
else nw=nw->rs;
}
if(ans!=NULL) splay(ans,root);
return ans;
}
void insert(int bg,int len,ll* arr){//不支持增加至已存在的节点
Splay_Node* lrt=kth(bg);
Splay_Node* rrt=kth(bg+1);
splay(lrt,root);
splay(rrt,lrt);
rrt->ls=build(1,len,rrt,arr);
update(rrt);
update(lrt);
}
void insert(ll sum){
if(root==NULL){
root=new Splay_Node(sum);
return;
}
Splay_Node* lrt=lower_bound(sum);
if(lrt!=NULL&&lrt->sum==sum){
lrt->self_siz++;
update(lrt);
return;
}
Splay_Node* rrt=upper_bound(sum);
splay(lrt,root);
splay(rrt,lrt);
Splay_Node* newnode=new Splay_Node(sum);
rrt->ls=newnode;
newnode->fa=rrt;
update(rrt);
update(lrt);
}
void erase(int bg,int ed){//全部删除区间内节点
Splay_Node* lrt=kth(bg);
Splay_Node* rrt=kth(ed+1);
splay(lrt,0);
splay(rrt,lrt);
clear(rrt->ls);
update(rrt);
update(lrt);
}
void erase(ll sum){
Splay_Node* rt=lower_bound(sum);
if(rt!=NULL||rt->sum!=sum) return;
splay(rt,root);
rt->self_siz--;
if(rt->self_siz>0){
update(rt);
return;
}
Splay_Node* lrt=rt->ls;
Splay_Node* rrt=rt->rs;
if(lrt!=NULL) lrt->fa=NULL;
if(rrt!=NULL) rrt->fa=NULL;
root=merge(lrt,rrt);
}
ll precursor(Splay_Node* rt,ll sum){
if(rt==NULL) return 0;
if(rt->sum>=sum) return precursor(rt->ls,sum);
ll rsum=precursor(rt->rs,sum);
if(!rsum) return rt->sum;
return rsum;
}
ll precursor(ll sum){
return precursor(root,sum);
}
ll successor(Splay_Node* rt,ll sum){
if(rt==NULL) return 0;
if(rt->sum<=sum) return successor(rt->rs,sum);
ll lsum=successor(rt->ls,sum);
if(!lsum) return rt->sum;
return lsum;
}
ll successor(ll sum){
return successor(root,sum);
}
void inorder(Splay_Node* rt){
if(rt==NULL) return;
inorder(rt->ls);
for(int i=1;i<=rt->self_siz;i++) O rt->sum;
inorder(rt->rs);
}
void inorder(){
inorder(root);
}
};
回复
共 0 条回复,欢迎继续交流。
正在加载回复...