splay模板 指针版&splay被卡祭

摘要:
普通平衡树板子参考了大佬博客访问空指针会出错,我用了一个nil代替他。-1:*bufs++;}inlinevoidxxx(){for(;;);}constintmxn=1e5+9;intn;#definelchch[0]#definerchch[1]#defineinfstructnode{node*ch[2],*prt;intsiz,cnt,val;inlinevoidup(){siz=cnt+lch-˃siz+rch-˃siz;}}*nil,SS[mxn],*stk[mxn];//stk就是提前申请内存模拟动态分配好像有点鸡肋classspl{public:node*rt;inttop;inlinevoidinit(){forstk[i]=SS+i;top=mxn-1;nil=stk[top--];nil-˃lch=nil-˃rch=nil-˃prt=nil,nil-˃cnt=nil-˃siz=0;rt=newd,rt-˃lch=newd,rt-˃siz=2;}inlinenode*newd{node*p=stk[top--];p-˃lch=p-˃rch=nil,p-˃prt=f;p-˃cnt=p-˃siz=1,p-˃val=v;returnp;}inlinevoidconnect{x-˃prt=f,f-˃ch[k]=x;}inlineintson{returnx==x-˃prt-˃rch;}inlinevoidrotate{node*f=x-˃prt,*g=f-˃prt;intk=son,kk=son;connect,connect;f-˃up(),x-˃up();ifrt=x,rt-˃prt=nil;elseconnect;}inlinevoidsplay{while(x-˃prt!=nil)p=p-˃rch;splay;p=rt-˃lch;p-˃rch=rt-˃rch,rt-˃rch-˃prt=p,p-˃up();stk[++top]=rt;rt=p,rt-˃prt=nil;}inlinenode*find{node*p=rt;while{ifreturnsplay,p;p=p-˃ch[p-˃valch[p-˃valcnt+p-˃lch-˃siz;ifbreak;p=nxt;}returnsplay,res;}inlinenode*kth{++x;node*p=rt;while{intnum=p-˃lch-˃siz;ifreturnsplay,p;ifp=p-˃lch;elsex-=num+p-˃cnt,p=p-˃rch;}}inlinenode*lower{returnkth;}inlinenode*upper{returnkth;}}sp;#undeflch#undefrch#undefinfintmain(){sp.init();scanf;while(n--){into,x;scanf;switch{case1:sp.insert;break;case2:sp.erase;break;case3:printf;break;case4:printf;break;case5:printf;break;case6:printf;break;}}return0;}原来的splay被卡了据我观察,这组数据很多人都跑不

普通平衡树板子

参考了大佬博客

访问空指针会出错,我用了一个nil代替他。(c++是谁设计的我还得把结构体定义在外面真难受)

#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> pii;
#define forg(i,x) for(int i=first[x];i;i=nxt[i])
#define uu unsigned
#define fi first
#define se second
#define od(x) ((x)&1)
#define ev(x) (od(x)^1)
#define mi2(x) (1<<(x))
#define scanf a1234=scanf
#define fre(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout)
int a1234;
char buf[1<<18],*bufs=buf,*buft=buf;
inline int gc(){
    return bufs==buft&&(buft=(bufs=buf)+fread(buf,1,1<<18,stdin)),bufs==buft?-1:*bufs++;
}
inline void xxx(){for(;;);}

const int mxn=1e5+9;
int n;
#define lch ch[0]
#define rch ch[1]
#define inf (0x3f3f3f3f)
struct node{
    node*ch[2],*prt;
    int siz,cnt,val;
    inline void up(){siz=cnt+lch->siz+rch->siz;}
}*nil,SS[mxn],*stk[mxn];
//stk就是提前申请内存 模拟动态分配 好像有点鸡肋
class spl{
    public:
    node*rt;int top;
    inline void init(){
        for(int i=0;i<mxn;++i)stk[i]=SS+i;
        top=mxn-1;
        nil=stk[top--];
        nil->lch=nil->rch=nil->prt=nil,nil->cnt=nil->siz=0;
        rt=newd(inf,nil),rt->lch=newd(-inf,rt),rt->siz=2;
    }
    inline node*newd(int v,node*f){
        node*p=stk[top--];
        p->lch=p->rch=nil,p->prt=f;
        p->cnt=p->siz=1,p->val=v;
        return p;
    }
    inline void connect(node*x,node*f,int k){
        x->prt=f,f->ch[k]=x;
    }
    inline int son(node*x){return x==x->prt->rch;}
    inline void rotate(node*x){
        node*f=x->prt,*g=f->prt;
        int k=son(x),kk=son(f);
        connect(x->ch[k^1],f,k),connect(f,x,k^1);
        f->up(),x->up();
        if(g==nil)rt=x,rt->prt=nil;else connect(x,g,kk);
    }
    inline void splay(node*x,node*y=nil){   
        while(x->prt!=y){
            node*f=x->prt,*g=f->prt;
            if(g==y)return rotate(x);
            if(son(x)^son(f))rotate(x),rotate(x);
            else rotate(f),rotate(x);
        }
    }
    inline void insert(int x){
        node*p=rt;
        while(1){
            ++p->siz;
            if(p->val==x)return ++p->cnt,splay(p);
            node*&nxt=p->ch[p->val<x];
            if(nxt==nil)return nxt=newd(x,p),splay(nxt);
            p=nxt;
        }
    }
    inline void erase(int x){
        find(x);
        --rt->cnt,--rt->siz;
        if(rt->cnt)return;
        node*p=rt->lch;
        while(p->rch!=nil)p=p->rch;
        splay(p,rt);
        p=rt->lch;
        p->rch=rt->rch,rt->rch->prt=p,p->up();
        stk[++top]=rt;
        rt=p,rt->prt=nil;
    }
    inline node*find(int x){
        node*p=rt;
        while(1){
            if(p->val==x)return splay(p),p;
            p=p->ch[p->val<x];
        }
    }
    inline int getrk(int x){
        node*p=rt,*nxt;
        int res=0;
        while(1){
            nxt=p->ch[p->val<x];
            if(p->val<x)res+=p->cnt+p->lch->siz;
            if(nxt==nil)break;
            p=nxt;
        }
        return splay(p),res;
    }
    inline node*kth(int x){
        ++x;
        node*p=rt;
        while(1){
            int num=p->lch->siz;
            if(num<x&&num+p->cnt>=x)return splay(p),p;
            if(x<=num)p=p->lch;
            else x-=num+p->cnt,p=p->rch;
        }
    }
    inline node*lower(int x){
        return kth(getrk(x)-1);
    }
    inline node*upper(int x){
        return kth(getrk(x+1));
    }
}sp;
#undef lch
#undef rch
#undef inf

int main(){
    sp.init();
    scanf("%d",&n);while(n--){
        int o,x;scanf("%d%d",&o,&x);
        switch(o){
            case 1:sp.insert(x);break;
            case 2:sp.erase(x);break;
            case 3:printf("%d
",sp.getrk(x));break;
            case 4:printf("%d
",sp.kth(x)->val);break;
            case 5:printf("%d
",sp.lower(x)->val);break;
            case 6:printf("%d
",sp.upper(x)->val);break;
        }
    }
    return 0;
}

原来的splay被卡了

据我观察,这组数据很多人都跑不过去,你要不要也试试呢,嘿嘿

为你奉上一份数据生成器

#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> pii;
#define forg(i,x) for(int i=first[x];i;i=nxt[i])
#define uu unsigned
#define fi first
#define se second
#define od(x) ((x)&1)
#define ev(x) (od(x)^1)
#define mi2(x) (1<<(x))
#define scanf a1234=scanf
#define fre(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout)
int a1234;
char buf[1<<18],*bufs=buf,*buft=buf;
inline int gc(){
    return bufs==buft&&(buft=(bufs=buf)+fread(buf,1,1<<18,stdin)),bufs==buft?-1:*bufs++;
}
inline void xxx(){for(;;);}

inline int rd(int l,int r){return rand()%(r-l+1)+l;}
int n=5e4;
inline void work(){
    printf("%d
",n*2);
    for(int i=1;i<=n;++i)printf("1 %d
",i*2);
    for(int i=1;i<=n;++i)printf("5 %d
",od(rand())?3:2*n+1);
}
int main(){
    srand((uu)time(0));
    work();
    return 0;
}

说句闲话,有个东西叫输入输出重定向,命令行里使的,比如./a <a.in >a.out可好用了

//被卡的代码
#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> pii;
#define forg(i,x) for(int i=first[x];i;i=nxt[i])
#define uu unsigned
#define fi first
#define se second
#define od(x) ((x)&1)
#define ev(x) (od(x)^1)
#define mi2(x) (1<<(x))
#define scanf a1234=scanf
#define fre(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout)
int a1234;
char buf[1<<18],*bufs=buf,*buft=buf;
inline int gc(){
    return bufs==buft&&(buft=(bufs=buf)+fread(buf,1,1<<18,stdin)),bufs==buft?-1:*bufs++;
}
inline void xxx(){for(;;);}

const int mxn=1e5+9;
int n;
#define lch ch[0]
#define rch ch[1]
#define inf (0x3f3f3f3f)
struct node{
    node*ch[2],*prt;
    int siz,cnt,val;
    inline void up(){siz=cnt+lch->siz+rch->siz;}
}*nil,SS[mxn],*stk[mxn];
class spl{
    public:
    node*rt;int top;
    inline void init(){
        for(int i=0;i<mxn;++i)stk[i]=SS+i;
        top=mxn-1;
        nil=stk[top--];
        nil->lch=nil->rch=nil->prt=nil,nil->cnt=nil->siz=0;
        rt=newd(inf,nil),rt->lch=newd(-inf,rt),rt->siz=2;
    }
    inline node*newd(int v,node*f){
        node*p=stk[top--];
        p->lch=p->rch=nil,p->prt=f;
        p->cnt=p->siz=1,p->val=v;
        return p;
    }
    inline void connect(node*x,node*f,int k){
        x->prt=f,f->ch[k]=x;
    }
    inline int son(node*x){return x==x->prt->rch;}
    inline void rotate(node*x){
        node*f=x->prt,*g=f->prt;
        int k=son(x),kk=son(f);
        connect(x->ch[k^1],f,k),connect(f,x,k^1);
        f->up(),x->up();
        if(g==nil)rt=x,rt->prt=nil;else connect(x,g,kk);
    }
    inline void splay(node*x,node*y=nil){   
        while(x->prt!=y){
            node*f=x->prt,*g=f->prt;
            if(g==y)return rotate(x);
            if(son(x)^son(f))rotate(x),rotate(x);
            else rotate(f),rotate(x);
        }
    }
    inline void insert(int x){
        node*p=rt;
        while(1){
            ++p->siz;
            if(p->val==x)return ++p->cnt,splay(p);
            node*&nxt=p->ch[p->val<x];
            if(nxt==nil)return nxt=newd(x,p),splay(nxt);
            p=nxt;
        }
    }
    inline void erase(int x){
        find(x);
        --rt->cnt,--rt->siz;
        if(rt->cnt)return;
        node*p=rt->lch;
        while(p->rch!=nil)p=p->rch;
        splay(p,rt);
        p=rt->lch;
        p->rch=rt->rch,rt->rch->prt=p,p->up();
        stk[++top]=rt;
        rt=p,rt->prt=nil;
    }
    inline node*find(int x){
        node*p=rt;
        while(1){
            if(p->val==x)return splay(p),p;
            p=p->ch[p->val<x];
        }
    }
    inline node*find1(int x){
        node*p=rt,*pres=nil;
        int res=-inf-2;
        while(p!=nil){
            if(p->val==x)return splay(p),p;
            if(p->val<x&&p->val>res)res=p->val,pres=p;
            p=p->ch[p->val<x];
        }
        return splay(pres),pres;
    }
    inline int getrk(int x){
        find1(x);
        return rt->val==x?rt->lch->siz:rt->cnt+rt->lch->siz;
    }
    inline node*kth(int x){
        ++x;
        node*p=rt;
        int cnt=0;
        while(1){
            int num=p->lch->siz;
            if(num<x&&num+p->cnt>=x)return splay(p),p;
            if(x<=num)p=p->lch;
            else x-=num+p->cnt,p=p->rch;
        }
    }
    inline node*lower(int x){
        return kth(getrk(x)-1);
    }
    inline node*upper(int x){
        return kth(getrk(x+1));
    }
}sp;
#undef lch
#undef rch
#undef inf

int main(){
    sp.init();
    scanf("%d",&n);while(n--){
        int o,x;scanf("%d%d",&o,&x);
        switch(o){
            case 1:sp.insert(x);break;
            case 2:sp.erase(x);break;
            case 3:printf("%d
",sp.getrk(x));break;
            case 4:printf("%d
",sp.kth(x)->val);break;
            case 5:printf("%d
",sp.lower(x)->val);break;
            case 6:printf("%d
",sp.upper(x)->val);break;
        }
    }
    return 0;
}

免责声明:文章转载自《splay模板 指针版&amp;amp;splay被卡祭》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Html 解决长串英文字母显示不能自动换行及 CSS中英文换行方法总结数据库操作封装类 DBHelper.cs下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

终于理解二级指针的作用了

之前学习swap函数时,知道传递指针可以实现对要交换变量本尊的修改,而直接传递值做不到这一点.究其原因,是因为函数传递参数时是以拷贝的形式,因此函数内部对其拷贝进行操作,不会影响到本尊. 如果想要通过函数实现对一级指针的值进行修改该如何去做呢?如果直接把它传进去,其实修改的是它的拷贝,而对它并没有影响.这个时候就是二级指针出场的时候了. #include...

C字符串和指针问题汇总

空指针和传参问题 1) 段错误。形参改为二级指针即可 void GetMemory( char *p ){   p = (char *) malloc( 100); } void Test( void){ char *str =NULL; GetMemory( str ); strcpy( str, "hello world"); prin...

C99规范

1. 增加restrict指针    C99中增加了公适用于指针的restrict类型修饰符,它是初始访问指针所指对象的惟一途径,因此只有借助restrict指针表达式才能访问对象。restrict指针指针主要用做函数变元,或者指向由malloc()函数所分配的内存变量。restrict数据类型不改变程序的语义。    如果某个函数定义了两个restr...

连通性

无向图的联通分量 割点:在一个联通分量里面有一些关键点,如果删除它,会把这个联通分量分为更多。 割边——双连通问题 有多少个割点:DFS,深搜优先生成树 对任意一个点s做DFS,生成一棵树 1)如果树的根节点s有两个或更多的孩子:s是割点 2)T的非根节点u是割点:当且仅当u存在一个子节点v,v及其后代都没有回退边连回u的祖先 HOW:u的直接后代v,数组...

【javaweb】库存物资管理系统思路与总结

题目: 1、有一个存放商品的仓库,每天都有商品出库和入库。 2、每种商品都有名称、生产厂家、型号、规格等。 3、出入库时必须填写出入库单据,单据包括商品名称、生产厂家、型号、 规格、数量、日期、时间、入库单位(或出库单位)名称、送货(或提货)人 姓名。 首先建立数据库goodsmanager table:goods记录商品信息 table:list记录出...

ZJOI 2019 划水记

作为一个极其蒟蒻的OIer,虽然没有省选资格但还是去见见世面。 ZJOI2019一试是在浙江省镇海中学。听名字就很霸气。 学习OI的最后一年,记录下一些事情,即使最终走到最后也一无所获,也是一段美好的记忆吧。 起码,我努力过。 ——ljc20020730 Day -1 20190323 晚上复习下基础数论,写了十几个板子(excrt,exgcd什么的),写...