非旋treap指针板子

普通平衡树:

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;

struct FHQ_Treap{
protected:
    struct node{
        node *ch[2];
        int siz,val,key;
        node(int siz=1,int val=0,int key=rand()):siz(siz),val(val),key(key){
            ch[0]=ch[1]=NULL;
        }
        void upd(){siz=(ch[0]?ch[0]->siz:0)+(ch[1]?ch[1]->siz:0)+1;}
        int rk(){return ch[0]?ch[0]->siz+1:1;}
    }poor[maxn],*tail,*root;
    void split(node *o,node *&a,node *&b,int val){
        if(!o){
            a=b=NULL;
            return;
        }
        if(o->val<=val){
            a=o;
            split(o->ch[1],a->ch[1],b,val);
            a->upd();
        }else{
            b=o;
            split(o->ch[0],a,b->ch[0],val);
            b->upd();
        }
    }
    void merge(node *&o,node *a,node *b){
        if(!a||!b){
            o=a?a:b;
            return;
        }
        if(a->key<=b->key){
            o=a;
            merge(o->ch[1],a->ch[1],b);
        }else{
            o=b;
            merge(o->ch[0],a,b->ch[0]);
        }
        o->upd();
    }
    node *kth(node *o,int k){
        while(o->rk()!=k){
            if(o->rk()<k)k-=o->rk(),o=o->ch[1];
            else o=o->ch[0];
        }
        return o;
    }
public:
    FHQ_Treap(){root=NULL;tail=poor;}
    void ins(int val){
        node *x=NULL,*y=NULL;
        node *z=new(tail++)node(1,val);
        split(root,x,y,val);
        merge(x,x,z);
        merge(root,x,y); 
    }
    void del(int val){
        node *x=NULL,*y=NULL,*z=NULL;
        split(root,x,y,val);
        split(x,x,z,val-1);
        merge(z,z->ch[0],z->ch[1]);
        merge(x,x,z);
        merge(root,x,y);
    }
    int rnk(int val){
        node *x=NULL,*y=NULL;
        split(root,x,y,val-1);
        int res=(x?x->siz:0)+1;
        merge(root,x,y);
        return res;
    }
    int kth(int rank){
        return kth(root,rank)->val;
    }
    int pre(int val) {
        node *x =NULL,*y=NULL;
        split(root,x,y,val-1);
        node *z=kth(x,x->siz);
        merge(root,x,y);
        return z->val;
    }
    int nxt(int val) {
        node *x=NULL,*y=NULL;
        split(root,x,y,val);
        node *z=kth(y,1);
        merge(root,x,y);
        return z->val;
    }
}fhq;
int n,opt,x;

int main(){
    scanf("%d",&n);
    while(n--){
        scanf("%d%d",&opt,&x);
        if(opt==1)fhq.ins(x);
        if(opt==2)fhq.del(x);
        if(opt==3)printf("%d\n",fhq.rnk(x));
        if(opt==4)printf("%d\n",fhq.kth(x));
        if(opt==5)printf("%d\n",fhq.pre(x));
        if(opt==6)printf("%d\n",fhq.nxt(x));
    }
    return 0;
}
View Code

文艺平衡树:

#include<bits/stdc++.h>
using namespace std;
struct node;typedef node* ptr;
const int maxn=1e5+5;

struct node{
    ptr ls,rs;
    int mark,size;
    int val,dat;
    
    node();
    ptr init(int v){
        val=v;size=1;
        mark=0;dat=rand();
        return this;
    }
    ptr pushd(){
        swap(ls,rs);
        mark^=1;
        return this;
    }
    ptr pushdown(){
        if(mark){
            ls->pushd();
            rs->pushd();
            mark=0;
        }
        return this;
    }
    ptr pushup(){
        size=ls->size+rs->size+1;
        return this;
    }
}e[maxn],*tail=e,*root=e;

node::node(){ls=rs=e;}
ptr newnode(int v){return (++tail)->init(v);}
void split(ptr p,ptr &x,ptr &y,int siz){
    if(p==e){
        x=y=e;
        return;
    }
    if(p->pushdown()->ls->size<siz){
        x=p;
        split(p->rs,p->rs,y,siz-p->ls->size-1);
    }else{
        y=p;
        split(p->ls,x,p->ls,siz);
    }
    p->pushup();
}
ptr merge(ptr x,ptr y){
    if(x==e)return y;
    if(y==e)return x;
    if(x->pushdown()->dat<y->pushdown()->dat){
        return x->rs=merge(x->rs,y),x->pushup();
    }else{
        return y->ls=merge(x,y->ls),y->pushup();
    } 
}
void mark(int l,int r){
    ptr x,y,p,q;
    split(root,x,y,r);
    split(x,p,q,l-1);
    root=merge(merge(p,q->pushd()),y);
}
void print(ptr p){
    p->pushdown();
    if(p->ls!=e)print(p->ls);
    printf("%d ",p->val);
    if(p->rs!=e)print(p->rs);
}
int n,m,l,r;

int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
        root=merge(root,newnode(i));
    while(m--){
        scanf("%d%d",&l,&r);
        mark(l,r);
    }
    print(root);
    return 0;
} 
View Code

 

posted @ 2020-12-19 13:07  _Famiglistimo  阅读(78)  评论(0编辑  收藏  举报