码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2019-02-13 22:34:34      阅读:268      评论:0      收藏:0      [点我收藏+]

标签:size   insert   col   span   clu   space   name   type   color   

解题关键:无旋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反转区间)

标签:size   insert   col   span   clu   space   name   type   color   

原文地址:https://www.cnblogs.com/elpsycongroo/p/10372079.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!