[知识点]Splay tree指针实现

早就想在成都把$splay$改成指针打法了。当时竟然没调出来。指针真难调。早上重新打了一遍,改过来了。

其实是为了打$lct$的。指针感觉会快,喵喵喵?

普通平衡树模板:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <vector>
using namespace std;
#define pos(i,a,b) for(int i=(a);i<=(b);i++)
#define N 101000
#define lc(x) (x->ch[0])
#define rc(x) (x->ch[1])
#define fa(x) (x->fa)
#define size(x) (x->size)
struct Splay{
    Splay *ch[2],*fa;
    int size,w,v;
    Splay(int x=0){ch[0]=ch[1]=fa=NULL;size=w=1;v=x;}
}*null,*root;
void init(){
    null=new Splay(0);
    lc(null)=rc(null)=fa(null)=null;null->size=null->w=0;
    root=null;
}
bool get(Splay *rt){return rc(rt->fa)==rt;}
void update(Splay *rt){if(rt) rt->size=size(lc(rt))+size(rc(rt))+rt->w;}
Splay *xin(Splay *fa,int x){
    Splay *now=new Splay(x);
    lc(now)=rc(now)=null;fa(now)=fa;
    if(fa!=null){
        fa->ch[fa->v < x]=now;
        update(fa);
    }
    return now;
}
void rotate(Splay *&rt){
    Splay *old=fa(rt),*oldf=fa(old);
    int d=get(rt);
    Splay *t=rt;old->ch[d]=t->ch[d^1];old->ch[d]->fa=old;
    t->ch[d^1]=old;old->fa=t;t->fa=oldf;
    if(oldf!=null) oldf->ch[rc(oldf)==old]=t;
    update(old);update(t);
    rt=t;
}
void splay(Splay *rt){
    for(Splay *fa;(fa=fa(rt))!=null;rotate(rt)){
        if(fa(fa)!=null) rotate((get(rt)==get(fa))?fa:rt);
    }
    root=rt;
}
void insert(Splay *&rt,Splay *fa,int x){
    if(rt==null){
        rt=xin(fa,x);splay(rt);
        return;
    }
    if(rt->v==x){
        rt->w++;update(rt);splay(rt);return;
    }
    int d=rt->v < x;
    insert(rt->ch[d],rt,x);
}
int pai(Splay *rt,int x){
    if(rt==null) return 0;
    if(x>rt->v) return size(lc(rt))+rt->w+pai(rc(rt),x);
    else if(x==rt->v){
        int ans=size(lc(rt))+1;splay(rt);
        return ans;;
    }
    else return pai(lc(rt),x);
}
int kth(Splay *rt,int k){
    if(k<=size(lc(rt))) return kth(lc(rt),k);
    else{
        int temp=size(lc(rt))+rt->w;
        if(k<=temp) return rt->v;
        else return kth(rc(rt),k-temp);
    }
}
Splay *pre(){
    Splay *now=lc(root);
    while(rc(now)!=null) now=rc(now);
    return now;
}
Splay *next(){
    Splay *now=rc(root);
    while(lc(now)!=null) now=lc(now);
    return now;
}
void del(int x){
    int whatever=pai(root,x);
    if(root->w>1){root->w--;update(root);return;}
    if(lc(root)==null&&rc(root)==null){root=null;return;}
    if(lc(root)==null){Splay *t=rc(root);delete root;root=t;root->fa=null;return;}
    if(rc(root)==null){Splay *t=lc(root);delete root;root=t;root->fa=null;return;}
    Splay *leftbig=pre(),*oldroot=root,*t=rc(oldroot);
    splay(leftbig);rc(root)=t;delete oldroot;fa(t)=root;
    update(root);
}
int main(){
    init();
    int n,opt,x;
    scanf("%d",&n);
    for (int i=1;i<=n;++i){
        scanf("%d%d",&opt,&x);
        switch(opt){
            case 1: insert(root,null,x); break;
            case 2: del(x); break;
            case 3: printf("%d\n",pai(root,x)); break;
            case 4: printf("%d\n",kth(root,x)); break;
            case 5: insert(root,null,x); printf("%d\n",pre()->v); del(x); break;
            case 6: insert(root,null,x); printf("%d\n",next()->v); del(x); break;
        }
    }
    return 0;
}
posted @ 2018-01-02 08:50 Hallmeow 阅读(...) 评论(...) 编辑 收藏