zoukankan      html  css  js  c++  java
  • loj 104 普通平衡树splay

    int n,root;//@树根@
    class splaytree{public:
        int fa[maxn],son[maxn][2],sz[maxn],val[maxn],cnt[maxn];
        int tot;//@root根val权值,cnt重复次数,sz子树大小@
        inline void pushup(int now){
            sz[now]=sz[son[now][0]]+sz[son[now][1]]+cnt[now];
        }//@更新当前节点信息@
        inline bool getson(int now) {
            return now==son[fa[now]][1];
        }//@真为右儿子@
        inline void clear(int now){
            fa[now]=son[now][0]=son[now][1]=sz[now]=val[now]=cnt[now]=0;
        }//@清空节点@
        inline void rotate(int now){
            int f=fa[now],gf=fa[fa[now]],flag=getson(now);
            son[f][flag]=son[now][flag^1];
            fa[son[now][flag^1]]=f;
            son[now][flag^1]=f;
            fa[f]=now;fa[now]=gf;
            if(gf) son[gf][f==son[gf][1]]=now;
            pushup(now);pushup(f);
        }//@旋转一层@
        void splay(int now){
            for(int f=fa[now];f=fa[now],f;rotate(now))
                if(fa[f]) rotate(getson(now)==getson(f)?f:now);
            root=now;
        }//@旋转到根@
        void insert(int x,int now=root,int f=0){
            if(!now){
                now=++tot;
                val[now]=x,cnt[now]++;
                if(!root)root=now;
                pushup(now);
                if(f){
                    fa[now]=f;
                    son[f][val[f]<x]=now;
                    pushup(f);
                    splay(now);
                }
            }else if(val[now]==x){
                ++cnt[now];
                pushup(now);pushup(f);
                splay(now);
            }else insert(x,son[now][val[now]<x],now);
        }//@插入新点@
        int getrank(int x,int now=root,int ans=0){
            while(1){
                if(x<val[now]) now=son[now][0];
                else {
                    ans+=sz[son[now][0]];
                    if(x==val[now]) return splay(now),ans+1;
                    ans+=cnt[now];now=son[now][1];
                }
            }
        }//@多少个元素小于x@
        int get(int k,int now=root){
            while(1){
                if(son[now][0]&&k<=sz[son[now][0]]) now=son[now][0];
                else {
                    k-=cnt[now]+sz[son[now][0]];
                    if(k<=0) return val[now];
                    now=son[now][1];
                }
            }
        }//查询第k大元素
        int pre(){
            int now=son[root][0];
            while(son[now][1]) now=son[now][1];
            return now;
        }//@前驱@
        int nxt(){
            int now=son[root][1];
            while(son[now][0]) now=son[now][0];
            return now;
        }//@后缀@
        int lower(int x){
            insert(x);int ans=val[pre()];erase(x);
            return ans;
        }//@查询前驱@@
        int upper(int x){
            insert(x);int ans=val[nxt()];erase(x);
            return ans;
        }//@查询后缀@
        void erase(int x){
            getrank(x);
            if(cnt[root]>1){
                --cnt[root];
                pushup(root);
            }else if(!son[root][0]&&!son[root][1]){
                clear(root);
                root=0;
            }else if(!son[root][0]||!son[root][1]){
                int t=root;
                if(!son[root][0]) root=son[root][1];
                else root=son[root][0];
                fa[root]=0;
                clear(t);
            }else {
                int now=pre(),t=root;
                splay(now);
                fa[son[t][1]]=now;
                son[now][1]=son[t][1];
                clear(t);
                pushup(root);
            }
        }//@删除x元素@
    }tree;
    int main() {
        cin>>n;
        while(n--){
            int opt,x;cin>>opt>>x;
            if(opt==1) tree.insert(x);
            if(opt==2) tree.erase(x);
            if(opt==3) cout<<tree.getrank(x)<<endl;
            if(opt==4) cout<<tree.get(x)<<endl;
            if(opt==5) cout<<tree.lower(x)<<endl;
            if(opt==6) cout<<tree.upper(x)<<endl;
        }
    	return 0;
    }
    

    整理一下板子

    换了种写法 递归和循环都有,

    属于比赛的时候翘起来很快的写法,速度比oiwiki上的板子慢了100ms左右吧

  • 相关阅读:
    R语言做文本挖掘 Part4文本分类
    在VS2005中使用原来的IIS调试Web程序(像VS2003一样)
    “提高一下dotnet程序的效率一”中关于exception的问题
    asp.net Cookies 转码的问题 中文丢失
    静态构造函数
    js在firefox中的问题
    模板引擎的一种实现
    .NET面试题,看看你的水平[转]
    转载 软件架构师应该具备的素质(Enterprise Solution Architects and Leadership)
    用正则表达式提取url中的Querystring参数
  • 原文地址:https://www.cnblogs.com/nervendnig/p/10987513.html
Copyright © 2011-2022 走看看