关闭

【伸展树】[CQBZOJ2803]普通平衡树splay模板

标签: c++数据结构
270人阅读 评论(0) 收藏 举报
分类:

贴代码

#include<cstdio>
#include<algorithm>
using namespace std;
#define MAXN 500000
int n,mi,ans;
struct node{
    int val,cnt,size;
    node *fa,*ch[2];
}splay_tree[MAXN+10],*tcnt=splay_tree,*root;
void Read(int &x){
    char c;
    bool f=0;
    while(c=getchar(),c!=EOF){
        if(c=='-')
            f=1;
        if(c>='0'&&c<='9'){
            x=c-'0';
            while(c=getchar(),c>='0'&&c<='9')
                x=x*10+c-'0';
            ungetc(c,stdin);
            if(f)
                x=-x;
            return;
        }
    }
}
inline int Get_size(node *p){
    return p?p->size:0;
}
inline void update(node *p){
    p->size=p->cnt+Get_size(p->ch[0])+Get_size(p->ch[1]);
}
void Rotate(node *a,int d){
    node *b=a->fa;
    b->ch[!d]=a->ch[d];
    a->fa=b->fa;
    if(a->ch[d])
        a->ch[d]->fa=b;
    if(b->fa)
        b->fa->ch[b==b->fa->ch[1]]=a;
    b->fa=a;
    a->ch[d]=b;
    update(b);
}
void splay(node *x,node *rt){
    node* y,*z;
    while(x->fa!=rt){
        y=x->fa;
        z=y->fa;
        if(z==rt){
            if(x==y->ch[0])
                Rotate(x,1);
            else
                Rotate(x,0);
        }
        else{
            if(y==z->ch[0])
                if(x==y->ch[0]){    //ZIG-ZIG
                    Rotate(y,1);
                    Rotate(x,1);
                }
                else{                    //ZAG-ZIG
                    Rotate(x,0);
                    Rotate(x,1);
                }
            else{
                if(x==y->ch[1]){  //ZAG-ZAG
                    Rotate(y,0);
                    Rotate(x,0);
                }
                else{                    //ZIG-ZAG
                    Rotate(x,1);
                    Rotate(x,0);
                }
            }
        }
    }
    update(x);
    if(!rt)
        root=x;
}
inline void clear(node *p){
    p->ch[0]=p->ch[1]=NULL;
}
void insert(int val){
    node *p=root,*fa=NULL;
    while(p){
        fa=p;
        if(p->val<val)
            p=p->ch[1];
        else if(p->val>val)
            p=p->ch[0];
        else{
            p->cnt++;
            splay(p,NULL);
            return;
        }
    }
    p=++tcnt;
    clear(p);
    p->cnt=1;
    p->fa=fa;
    if(fa){
        if(val<fa->val)
            fa->ch[0]=p;
        else
            fa->ch[1]=p;
    }
    else
        root=p;
    p->val=val;
    splay(p,NULL);
}
node *find(node *x,int d){
    while(x&&x->ch[d])
        x=x->ch[d];
    return x;
}
void del(int val){
    node *p=root;
    while(p){
        if(val<p->val)
            p=p->ch[0];
        else if(val>p->val)
            p=p->ch[1];
        else{
            if(p->cnt>1){
                p->cnt--;
                splay(p,NULL);
                return;
            }
            else{
                splay(p,NULL);
                node *ft=find(p->ch[0],1),*bk=find(p->ch[1],0);
                if(!ft&&!bk)
                    root=NULL;
                else if(!ft)
                    root=root->ch[1],root->fa=NULL;
                else if(!bk)
                    root=root->ch[0],root->fa=NULL;
                else{
                    splay(ft,NULL);
                    splay(bk,root);
                    bk->ch[0]=NULL;
                    bk->size--;
                    ft->size--;
                }
            }
            return;
        }
    }
}
int find_pos(int val){
    node *p=root;
    int ret=0;
    while(p){
        if(val<p->val)
            p=p->ch[0];
        else if(val>p->val){
            ret+=Get_size(p->ch[0])+p->cnt;
            p=p->ch[1];
        }
        else
            return ret+Get_size(p->ch[0])+1;
    }
    splay(p,NULL);
}
int pos_find(int pos){
    node *p=root;
    while(p){
        if(!pos){
            p=find(p,0);
            return p->val;
        }
        if(pos<Get_size(p->ch[0]))
            p=p->ch[0];
        else if(pos>=Get_size(p->ch[0])+p->cnt)
            pos-=Get_size(p->ch[0])+p->cnt,p=p->ch[1];
        else
            return p->val;
    }
    splay(p,NULL);
}
int find_bk(int val){
    insert(val);
    int ret=find(root->ch[1],0)->val;
    del(val);
    return ret;
}
int find_ft(int val){
    insert(val);
    int ret=find(root->ch[0],1)->val;
    del(val);
    return ret;
}
int main()
{
    Read(n);
    int a,b;
    while(n--){
        Read(a),Read(b);
        if(a==1)
            insert(b);
        else if(a==2)
            del(b);
        else if(a==3)
            printf("%d\n",find_pos(b));
        else if(a==4)
            printf("%d\n",pos_find(b-1));
        else if(a==5)
            printf("%d\n",find_ft(b));
        else
            printf("%d\n",find_bk(b));
    }

}
0
0
查看评论

【伸展树】[CQBZOJ2803]普通平衡树splay top_down模板

贴模板#include<cstdio> #include<algorithm> using namespace std; #define MAXN 500000 using namespace std; int n; void Read(int &x){ ch...
  • outer_form
  • outer_form
  • 2015-11-28 23:19
  • 322

bzoj3224 普通平衡树【splay版】

平衡树模板题。splay版。
  • sdfzyhx
  • sdfzyhx
  • 2016-05-16 23:12
  • 989

Splay伸展树模板总结

1.基本点操作 //Splay 基本操作 均摊复杂度O(lgN) //POJ 1442 //基本点操作 // sp.init() 初始化 #include #include #include using namespace std; #define maxn 31000 #...
  • snk1996
  • snk1996
  • 2015-09-04 16:20
  • 824

史上最详尽的平衡树(splay)讲解与模板

所有的结局都已写好,所有的泪水也都已启程,却忽然忘了,是怎麽样的一个开始。在那个古老的,不再回来的夏日,无论我如何地去追索,年轻的你只如云影掠过。而你微笑的面容,极浅极淡,逐渐隐没在日落后的群岚。遂翻开那发黄的扉页,命运将它装订得极为拙劣。含著泪,我一读再读,却不得不承认,青春,是一本太仓促的书。
  • Clove_unique
  • Clove_unique
  • 2016-02-03 20:59
  • 10585

AVL树、splay树(伸展树)和红黑树比较

一、AVL树: 优点:查找、插入和删除,最坏复杂度均为O(logN)。实现操作简单     如过是随机插入或者删除,其理论上可以得到O(logN)的复杂度,但是实际情况大多不是随机的。如果是随机的,则AVL     树能够达到比RB树更优的结果,因为...
  • u010585135
  • u010585135
  • 2014-12-10 21:58
  • 2611

Splay伸展树&模板

伸展树操作详解 http://wenku.baidu.com/view/cc211f126edb6f1aff001f16.html?from=rec&pos=4&weight=9&lastweight=9&count=5 The Magica...
  • leolin_
  • leolin_
  • 2011-05-21 09:57
  • 7459

洛谷P3369 普通平衡树(Treap/Splay)

题目描述您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作: 1. 插入x数 2. 删除x数(若有多个相同的数,因只删除一个) 3. 查询x数的排名(若有多个相同的数,因输出最小的排名) 4. 查询排名为x的数 5. 求x的前驱(前驱定义为小于x,且最大的数)...
  • Ab_Ever
  • Ab_Ever
  • 2017-04-17 11:50
  • 351

bzoj 3224==tyvj 1728普通平衡树 splay

啊啊啊啊今天各种煞笔啊。。 首先早晨起晚了。。一晚上从11点睡到了7点。。 下午大概三点半开始写这个题。。各种不顺以后发现70分一直超时。。各种方法都不行,后来直接把lyw的子程序都闹过来结果成60 了。。。 最后在6点20 的时候发现了一个恶心的问题!!!! 应该用printf但是我用的是...
  • u012457935
  • u012457935
  • 2013-12-05 18:41
  • 2241

bzoj 3223 文艺平衡树 Splay详细解析

本文不会过于深入介绍splay的证明,感性认知- -。 对于树我们知道它有两个旋转,对于一个节点,如果它是左儿子,那么它只能右旋,如果它是右儿子,它只能左旋,在splay的时候,我们的目的是把一个节点x转到一个根上,我们考虑两种情况, 1在三点一线的时候(3个点没有弯曲)那么先旋转x的父亲,在旋...
  • Kamisama123
  • Kamisama123
  • 2017-07-14 20:51
  • 320

序列神器伸展树 区间维护,区间提取,区间翻转的AC模板。

如果不懂splay,请进入百度文库,如果看懂了就忽略此文 题源:poj3580 splay,伸展树,是一颗功能好的平衡树,它通过把操作过的询问旋到根,来节省时间,使得总时间为log(迷之常数....)所以我们要维护一个序列,就不能像treap那样通过权值大小忽略位置地直接比较,以下是要注意的...
  • qq_30446721
  • qq_30446721
  • 2016-12-14 22:48
  • 538
    个人资料
    • 访问:100105次
    • 积分:2719
    • 等级:
    • 排名:第15724名
    • 原创:171篇
    • 转载:1篇
    • 译文:0篇
    • 评论:52条
    Contact me
    欢迎各位神犇对我博客中的错误进行指正,或和我进行交流
    最新评论