社区讨论

极其优秀的Splay

P3369【模板】普通平衡树参与者 14已保存回复 13

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
13 条
当前快照
1 份
快照标识符
@mi6tk7hi
此快照首次捕获于
2025/11/20 10:35
4 个月前
此快照最后确认于
2025/11/20 13:50
4 个月前
查看原帖
转载来自Menteur_Hxy
CPP
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<algorithm>
#include<cstring>
using namespace std;

const int _=200010;

int n,____________,x,________,_________;
int __[_][2],___[_],____[_],_____[_],______[_];

inline void clear(int x) {
    __[x][1]=__[x][0]=___[x]=____[x]=_____[x]=______[x]=0;
}

inline bool get(int x) {
    return __[____[x]][1]==x;
}

inline void update(int x){
    if(x) {
        ___[x]=_____[x];
        if(__[x][1]) ___[x]+=___[__[x][1]];
        if(__[x][0]) ___[x]+=___[__[x][0]];
    }
}

inline void rotate(int x) {
    int old=____[x],__________=____[old],___________=get(x);
    __[old][___________]=__[x][___________^1]; 
    ____[__[old][___________]]=old;
    ____[old]=x; __[x][___________^1]=old;
    ____[x]=__________;
    if(__________) __[__________][__[__________][1]==old]=x;
    update(old);update(x);
}

inline void splay(int x) {
    for(int f;f=____[x];rotate(x))
        if(____[f]){
            if(get(x)==get(f)) rotate(f);
            else rotate(x);
        }   
    ________=x;
}

inline void insert(int x) {
    if(!________) {
        _________++;________=_________;
        __[_________][0]=__[_________][1]=____[_________]=0;
        ___[_________]=_____[_________]=1;
        ______[_________]=x;
        return ;
    }
    int _______=________,f=0;
    while(1) {
        if(______[_______]==x) {
            _____[_______]++;update(_______);update(f);splay(_______);break;
        }
        f=_______;
        _______=__[_______][______[_______]<x];
        if(_______==0) {
            _________++;
            __[_________][0]=__[_________][1]=0;
            ___[_________]=_____[_________]=1;
            ____[_________]=f;______[_________]=x;
            __[f][______[f]<x]=_________;
            update(f);
            splay(_________);//ΪpreºÍnext×ö×¼±¸ 
            break;
        }
    }
}

inline int find1(int x) {
    int ans=0,_______=________;
    while(1){
        if(x<______[_______]) _______=__[_______][0];
        else {
            ans+=__[_______][0]?___[__[_______][0]]:0;
            if(x==______[_______]) {
                splay(_______);
                return ans+1;
            }
            else {
                ans+=_____[_______];
                _______=__[_______][1];
            }
        }
    }
}

inline int find2(int x) {
    int _______=________;
    while(1){
        if(__[_______][0]&&x<=___[__[_______][0]]) 
            _______=__[_______][0];
        else {
            int _____________=(__[_______][0]?___[__[_______][0]]:0)+_____[_______];
            if(x<=_____________) return ______[_______];
            x-=_____________,_______=__[_______][1];
        }
    }
}

inline int pre() {
    int _______=__[________][0];
    while(__[_______][1]) _______=__[_______][1];
    return _______;
}

inline int next() {
    int _______=__[________][1];
    while(__[_______][0]) _______=__[_______][0];
    return _______;
}

inline void del(int x) {
    find1(x);
    if(_____[________]>1) {
        _____[________]--;
        update(________);
    }
    else if(!__[________][0]&&!__[________][1]) {
        clear(________);________=0;
    }
    else if(!__[________][0]) {
        int old=________;
        ________=__[________][1];
        ____[________]=0;
        clear(old);
    }
    else if(!__[________][1]) {
        int old=________;
        ________=__[________][0];
        ____[________]=0;
        clear(old);
    }
    else {
        int lbig=pre(),old=________;
        splay(lbig);
        __[________][1]=__[old][1];
        ____[__[old][1]]=________;
        clear(old);
        update(________);
    }
    return ;
}

int main() {
    scanf("%d",&n);
    for(int i=1;i<=n;i++) {
        scanf("%d %d",&____________,&x);
        switch(____________) {
            case 1:insert(x);break;
            case 2:del(x);break;
            case 3:printf("%d\n",find1(x));break;
            case 4:printf("%d\n",find2(x));break;
            case 5:insert(x);printf("%d\n",______[pre()]);del(x);break;
            case 6:insert(x);printf("%d\n",______[next()]);del(x);break;   
        }
    }
    return 0;
}

回复

13 条回复,欢迎继续交流。

正在加载回复...