[luogu3391] 模板文艺平衡树(fhq-treap反转区间)

Posted elpsycongroo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[luogu3391] 模板文艺平衡树(fhq-treap反转区间)相关的知识,希望对你有一定的参考价值。

解题关键:无旋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(int now,int k,int &x,int &y){
    if(!now) x=y=0;
    else{
        pushdown(now);
        if(val[now]<=k) x=now,split(ch[now][1],k,ch[now][1],y);
        else y=now,split(ch[now][0],k,x,ch[now][0]);
        pushup(now);
    }
}
*/
//排名分裂

void split(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(ch[now][0],k,x,ch[now][0]);}
        else{x=now;split(ch[now][1],k-size[ch[now][0]]-1,ch[now][1],y);}
        pushup(now);
    }
}

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

void reverse(int &k,int l,int r){
    split(k,l-1,x,y);
    split(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;
}

 

以上是关于[luogu3391] 模板文艺平衡树(fhq-treap反转区间)的主要内容,如果未能解决你的问题,请参考以下文章

[Splay]luogu P3391 文艺平衡树

luogu P3391 文艺平衡树

[luogu3391][文艺平衡树]

P3391 模板文艺平衡树(Splay)

P3391 模板文艺平衡树(Splay)新板子

luoguP3391[模板]文艺平衡树(Splay) 题解