浅谈fhq_treap

Posted hzf29721

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了浅谈fhq_treap相关的知识,希望对你有一定的参考价值。

#include<bits/stdc++.h>
#define ll long long
#define F(i,j,n) for(register int i=j;i<=n;i++)
#define mem(i,j) memset(i,j,sizeof(i))
#define INF 0x3f3f3f3f
using namespace std;
int n,m;
inline int read(){
    int datta=0;char chchc=getchar();bool okoko=0;
    while(chchc<'0'||chchc>'9'){if(chchc=='-')okoko=1;chchc=getchar();}
    while(chchc>='0'&&chchc<='9'){datta=datta*10+chchc-'0';chchc=getchar();}
    return okoko?-datta:datta;
}
class Fhq_Treap{
public:
    int rt,tot,son[100010][2],key[100010],val[100010],sz[100010],mx[100010],add[100010];
    bool rev[100010];
    inline void updata(int u){
        sz[u]=sz[son[u][0]]+sz[son[u][1]]+1;
        mx[u]=max(max(val[u],mx[son[u][0]]),mx[son[u][1]]);
    }
    inline void build(int l,int r,int lst){
        if(r<l)
            return ;
        if(l==r){
            son[lst][lst<l]=l;
            key[l]=rand();
            sz[l]=1;
            return ;
        }
        int mid=(l+r)>>1;
        son[lst][lst<mid]=mid;
        key[mid]=rand();
        build(l,mid-1,mid);
        build(mid+1,r,mid);
        updata(mid);
    }
    inline void prepare(){
        tot=n;
        rt=(1+n)>>1;
        build(1,n,0);
        mx[0]=-2e9;
    }
    inline void make_add_tag(int u,int v){
        add[u]+=v;
        val[u]+=v;
        mx[u]+=v;
    }
    inline void make_rev_tag(int u){
        rev[u]^=1;
        swap(son[u][0],son[u][1]);
    }
    inline pair<int,int>split(int u,int k){
        if(!k)
            return make_pair(0,u);
        if(k==sz[u])
            return make_pair(u,0);
//      if(rev[u])
            pushdown(u);
        if(k<=sz[son[u][0]]){
            pair<int,int>res=split(son[u][0],k);
            son[u][0]=res.second;
            updata(u);
            return make_pair(res.first,u);
        }else{
            pair<int,int>res=split(son[u][1],k-sz[son[u][0]]-1);
            son[u][1]=res.first;
            updata(u);
            return make_pair(u,res.second);
        }
    }
    inline void pushdown(int u){
        if(rev[u]){
            if(son[u][0])
                make_rev_tag(son[u][0]);
            if(son[u][1])
                make_rev_tag(son[u][1]);
            rev[u]=0;
        }
        if(add[u]){
            if(son[u][0])
                make_add_tag(son[u][0],add[u]);
            if(son[u][1])
                make_add_tag(son[u][1],add[u]);
            add[u]=0;
        }
    }
    inline int merge(int x,int y){
        if(!x||!y)
            return x+y;
        pushdown(x);
        pushdown(y);
        if(key[x]<key[y]){
            son[x][1]=merge(son[x][1],y);
            updata(x);
            return x;
        }else{
            son[y][0]=merge(x,son[y][0]);
            updata(y);
            return y;
        }
    }
}F;
int main(){
    srand(time(0));
    n=read();m=read();
    F.prepare();
    F(ii,1,m){
        int kd=read();
        if(kd==1){
            int l=read(),r=read(),kk=read();
            pair<int,int>spl1=F.split(F.rt,r);
            pair<int,int>spl2=F.split(spl1.first,l-1);
    //      printf("dgsgdfshgsdfg
");
            F.make_add_tag(spl2.second,kk);
            F.rt=F.merge(F.merge(spl2.first,spl2.second),spl1.second);
        }else{
            if(kd==2){
                int l=read(),r=read();
                pair<int,int>spl1=F.split(F.rt,r);
                pair<int,int>spl2=F.split(spl1.first,l-1);
                F.make_rev_tag(spl2.second);
                F.rt=F.merge(F.merge(spl2.first,spl2.second),spl1.second);
            }else{
                int l=read(),r=read();
                pair<int,int>spl1=F.split(F.rt,r);
                pair<int,int>spl2=F.split(spl1.first,l-1);
                printf("%d
",F.mx[spl2.second]);
                F.rt=F.merge(F.merge(spl2.first,spl2.second),spl1.second);
            }
        }
    }
    return 0;
}

以上是关于浅谈fhq_treap的主要内容,如果未能解决你的问题,请参考以下文章

「模板」 FHQ_Treap

「模板」 FHQ_Treap 区间翻转

神仙数据结构——FHQ_Treap

浅谈Mybatis

[luogu 3369]普通平衡树(fhq_treap)

浅谈AngularJS中的$parse和$eval