zoukankan      html  css  js  c++  java
  • 如何用treap写luogu P3391

    treap大法好!!!
    splay什么的都是异端
    ——XZZ

    先%FHQ为敬

    (fhq)treap也是可以搞区间翻转的
    每次把它成(1~L-1)(L~R)(R+1~n)三块然后打标记拼回去
    对于有标记的先交换一下左右儿子再异或一下各儿子的标记
    虽说跑的不算快但还是可以挑战一下splay的
    代码蒯上

    //get out splay!
    #include<iostream>
    #include<iomanip>
    #include<cmath>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    inline int gotcha()
    {
        register int _a=0;bool _b=1;register char _c=getchar();
        while((_c<'0' || _c>'9') && _c!='-')_c=getchar();
        if(_c=='-')_b=0,_c=getchar();
        while(_c>='0' && _c<='9')_a=_a*10+_c-48,_c=getchar();
        return _b?_a:-_a;
    }
    const int _ = 100007;int seed=19260817;
    inline int ou(){return seed=seed*17283%2147483647;}//看RP的时候到了
    int ch[_][2],d[_],rn[_],sz[_],all=0,n,root=0;
    int rev[_];
    inline void up(int x){sz[x]=1+sz[ch[x][0]]+sz[ch[x][1]];}//更新节点值
    inline void down(int x)//向下传递翻转标记
    {
        if(x && rev[x])
        {
            rev[x]=0,swap(ch[x][0],ch[x][1]);
            if(ch[x][0])rev[ch[x][0]]^=1;
            if(ch[x][1])rev[ch[x][1]]^=1;
        }
    }
    inline int malloc(int v){sz[++all]=1;d[all]=v;rn[all]=ou();return all;}//新建一个节点
    inline int merge(int a,int b)
    {
        if(!a || !b) return a+b;down(a),down(b);
        if(rn[a]<rn[b]){ch[a][1]=merge(ch[a][1],b);up(a);return a;}
        else{ch[b][0]=merge(a,ch[b][0]);up(b);return b;}
    }
    void split(int now,int k,int &a,int &b)
    {
        if(!now){a=b=0;return;}
        down(now);
        if(k<=sz[ch[now][0]])b=now,split(ch[now][0],k,a,ch[now][0]);
        else a=now,split(ch[now][1],k-sz[ch[now][0]]-1,ch[now][1],b); 
        up(now);
    }
    int plant(int l,int r)//种树
    {
        if(l>r)return 0;
        int mid=(l+r)>>1,now=malloc(mid-1);
        ch[now][0]=plant(l,mid-1);ch[now][1]=plant(mid+1,r);
        up(now);return now;
    }
    void print(int now)//按中序遍历输出答案
    {
        if(!now)return;down(now);
        print(ch[now][0]);
        if(d[now]>=1 && d[now]<=n)printf("%d ",d[now]);
        print(ch[now][1]);
        return;
    }
    void reverse(int l,int r)//旋转
    {
        int a,b,c;
        split(root,l-1,a,b),split(b,r-l+1,b,c);
        rev[b]^=1;
        root=merge(a,merge(b,c));
    }
    int main()
    {
        register int m,l,r;
        n=gotcha();m=gotcha();
        root=plant(2,n+3);
        while(m--)
        {
            l=gotcha(),r=gotcha();
            reverse(l,r);
        }
        print(root);
        return 0;
    }
    

    treap坠强!

  • 相关阅读:
    ubuntu18.04 扩展根目录 亲测有效
    mysql数据恢复
    java多线程
    jenkins安装搭建及使用
    springboot web开发
    git版本管理
    docker安装部署项目
    vue nuxt项目部署
    IntelliJ IDEA常用快捷键
    IntelliJ IDEA常用设置
  • 原文地址:https://www.cnblogs.com/finder-iot/p/7601192.html
Copyright © 2011-2022 走看看