• 【模板】Splay(洛谷P3391)


    Background

    这是一道经典的( ext Splay)模板题——文艺平衡树。

    Description

    您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是(5 4 3 2 1),翻转区间是([2,4])的话,结果是(5 2 3 4 1)

    Input

    第一行为(n,m) (n)表示初始序列有(n)个数,这个序列依次是 ((1,2, cdots n-1,n)) (m)表示翻转操作次数

    接下来(m)行每行两个数 ([l,r]) 数据保证 (1 leq l leq r leq n)

    Output

    输出一行(n)个数字,表示原始序列经过(m)次变换后的结果

    Code

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #define lson(x) son[x][0]
    #define rson(x) son[x][1]
    using namespace std;
    int n,m,root,siz[200010],fa[200010],son[200010][2],tag[200010];
    void updata(int u)
    {
        siz[u]=siz[lson(u)]+siz[rson(u)]+1;
    }
    void down(int u)
    {
        if (tag[u])
        {
            swap(lson(u),rson(u));
            tag[u]^=1;tag[lson(u)]^=1;tag[rson(u)]^=1;
        }
    }
    void build(int l,int r,int f)
    {
        if (l>r) return;
        if (l==r)
        {
            fa[l]=f,siz[l]=1;
            son[f][l>f]=l;
            return;
        }
        int mid=(l+r)>>1;
        build(l,mid-1,mid),build(mid+1,r,mid);
        son[f][mid>f]=mid;fa[mid]=f;
        updata(mid);
    }
    int find(int rt,int k)
    {
        down(rt);
        if (siz[lson(rt)]+1==k) return rt;
        if (siz[lson(rt)]>=k) return find(lson(rt),k);
        else return find(rson(rt),k-siz[lson(rt)]-1);
    }
    void rotate(int x,int &rt)
    {
        int y=fa[x],z=fa[y],t=(rson(y)==x);
        if (y==rt) rt=x; else son[z][rson(z)==y]=x;
        fa[x]=z,fa[y]=x,fa[son[x][t^1]]=y;
        son[y][t]=son[x][t^1];son[x][t^1]=y;
        updata(y);updata(x);
    }
    void splay(int x,int &rt)
    {
        while (x!=rt)
        {
            int y=fa[x],z=fa[y];
            if (y!=rt)
                if (lson(z)==y ^ lson(y)==x) rotate(x,root);
                else rotate(y,root);
            rotate(x,root);
        }
    }
    void rever(int l,int r)
    {
        l=find(root,l);r=find(root,r+2);
        splay(l,root),splay(r,rson(root));
        tag[lson(rson(root))]^=1;
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        root=(n+3)>>1;
        build(1,n+2,0);
        while (m--)
        {
            int l,r;
            scanf("%d%d",&l,&r);
            rever(l,r);
        }
        for (int i=2;i<=n+1;i++)
            printf("%d ",find(root,i)-1);
        return 0;
    }
    
  • 相关阅读:
    linux mint安装成功
    js 兼容性
    程序员的肚子有多大,水平就有多高
    财富通直连接口for rails3
    ubuntu live cd版本是没有recuse broken system功能
    生活百科
    省市县导入mysql代码,通过csv
    省市县导入mysql代码,通过csv
    休眠、挂起、待机三者之间的区别 收藏
    支付宝接口for rails3
  • 原文地址:https://www.cnblogs.com/Code-Geass/p/10293970.html
Copyright © 2020-2023  润新知