fhq-treap模板

模板保存。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<ctime>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#define maxn 500001
using namespace std;
typedef long long ll;
int size[maxn],ch[maxn][2],rnd[maxn],val[maxn],rev[maxn];
int ncnt,x,y,z,rt,n,m;

inline void pushup(int x){
    size[x]=1+size[ch[x][0]]+size[ch[x][1]];
}

inline void pushdown(int rt){
    if(rev[rt]){
        swap(ch[rt][0],ch[rt][1]);
        if(ch[rt][0]) rev[ch[rt][0]]^=1;
        if(ch[rt][1]) rev[ch[rt][1]]^=1;
        rev[rt]=0;
    }

}

inline int new_node(int x){
    size[++ncnt]=1;
    val[ncnt]=x;
    rnd[ncnt]=rand();
    return ncnt;
}
//核心
int merge(int A,int B){
    if(!A||!B) return  A+B;
    if(rnd[A]<rnd[B]){pushdown(A);ch[A][1]=merge(ch[A][1],B);pushup(A);return A;}
    else {pushdown(B);ch[B][0]=merge(A,ch[B][0]);pushup(B);return B;}
}
//权值分裂

void split_1(int now,int k,int &x,int &y){
    if(!now) x=y=0;
    else{
        pushdown(now);
        if(val[now]<=k) x=now,split_1(ch[now][1],k,ch[now][1],y);
        else y=now,split_1(ch[now][0],k,x,ch[now][0]);
        pushup(now);
    }
}

//排名分裂

void split_2(int now,int k,int &x,int &y){
    if(!now) x=y=0;
    else{
        pushdown(now);
        if(k<=size[ch[now][0]]){y=now;split_2(ch[now][0],k,x,ch[now][0]);}
        else{x=now;split_2(ch[now][1],k-size[ch[now][0]]-1,ch[now][1],y);}
        pushup(now);
    }
}

void insert(int &k,int a){
    split_1(k,a,x,y);
    k=merge(merge(x,new_node(a)),y);
}

//会浪费空间,没有回收节点
void del(int &k,int a){
    split_1(k,a,x,z);
    split_1(x,a-1,x,y);
    y=merge(ch[y][0],ch[y][1]);
    k=merge(merge(x,y),z);
}

int rnk(int &k,int a){
    split_1(k,a-1,x,y);
    int res=size[x]+1;
    k=merge(x,y);
    return res;
}

int kth(int now,int k){
    while(1){
        if(k<=size[ch[now][0]]) now=ch[now][0];
        else if(k==size[ch[now][0]]+1) return val[now];
        else k-=size[ch[now][0]]+1,now=ch[now][1];
    }
}

int pred(int &k,int a){
    split_1(k,a-1,x,y);
    int res=kth(x,size[x]);
    k=merge(x,y);
    return res;
}

int succ(int &k,int a){
    split_1(k,a,x,y);
    int res=kth(y,1);
    k=merge(x,y);
    return res;
}

void reverse(int &k,int l,int r){
    split_2(k,l-1,x,y);
    split_2(y,r-l+1,y,z);
    rev[y]^=1;
    k=merge(x,merge(y,z));
}

void print(int &k){
    if(!k) return;
    pushdown(k);
    print(ch[k][0]);
    if(val[k]>=1&&val[k]<=n) printf("%d ",val[k]);
    print(ch[k][1]);
}

int main(){
    srand(time(0));
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++) insert(rt,i);
    for(int i=1,l,r;i<=m;i++){
        scanf("%d%d",&l,&r);
        reverse(rt,l,r);
    }
    print(rt);
    return 0;
}

 

posted @ 2019-02-13 22:30  Elpsywk  阅读(221)  评论(0编辑  收藏  举报