• BZOJ1500[NOI2005]维修数列——非旋转treap


    题目描述

    请写一个程序,要求维护一个数列,支持以下 6 种操作:
    请注意,格式栏 中的下划线‘ _ ’表示实际输入文件中的空格

    输入

    输入的第1 行包含两个数N 和M(M ≤20 000),N 表示初始时数列中数的个数,M表示要进行的操作数目。
    第2行包含N个数字,描述初始时的数列。
    以下M行,每行一条命令,格式参见问题描述中的表格。
    任何时刻数列中最多含有500 000个数,数列中任何一个数字均在[-1 000, 1 000]内。
    插入的数字总数不超过4 000 000个,输入文件大小不超过20MBytes。

    输出

    对于输入数据中的GET-SUM和MAX-SUM操作,向输出文件依次打印结果,每个答案(数字)占一行。

    样例输入

    9 8
    2 -6 3 5 1 -5 -3 6 3
    GET-SUM 5 4
    MAX-SUM
    INSERT 8 3 -5 7 2
    DELETE 12 1
    MAKE-SAME 3 3 2
    REVERSE 3 6
    GET-SUM 5 4
    MAX-SUM

    样例输出

    -1
    10
    1
    10

    提示

    这道题的区间操作十分全,无论是用非旋转treap还是splay写,都会有更深入的理解。

    讲一下每个操作的实现

    1、将插入的数再建一棵treap,然后把原treap断裂,把新建treap合并进去。

    2、把treap断裂成三部分,然后再把左右两部分合并。

    3、也是把treap断裂成三部分,把中间部分打标记,标记在合并时下传。

    4、和上面一样,也是断裂成三部分,中间打标记。

    5、断裂成三部分,输出中间部分根节点的子树和。

    6、直接输出根节点的最大连续子段和。

    最后不要忘了资源回收(回收节点编号)

    最后附上代码(有注释)

    #include<queue>
    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    int num;
    int pos;
    int tot;//树的大小
    int root;//根节点
    int n,k,g;
    int x,y,z;
    int b,c,d;
    char ch[5];
    queue<int>q;//资源回收队列
    int a[200010];//插入序列及初始序列
    int m[500010];//区间最大子段和
    int s[500010];//翻转标记
    int f[500010];//修改标记
    int r[500010];//随机数
    int ls[500010];//左儿子
    int rs[500010];//右儿子
    int lm[500010];//子树区间中从左端点开始的最大连续子段和
    int rm[500010];//子树区间中以右端点结束的最大连续子段和
    int val[500010];//节点权值
    int sum[500010];//子树区间和
    int size[500010];//子树大小
    int INF=2147483647;
    int insert(int v)
    {
        int x;
        if(!q.empty())
        {
            x=q.front();
            q.pop();
        }
        else
        {
            x=++tot;
        }
        size[x]=1;
        ls[x]=rs[x]=s[x]=0;
        f[x]=INF;
        r[x]=rand();
        val[x]=sum[x]=v;
        lm[x]=rm[x]=m[x]=v;
        return x;
    }
    void updata(int x)
    {
        if(!x)
        {
            return ;
        }
        size[x]=size[ls[x]]+size[rs[x]]+1;
        sum[x]=sum[ls[x]]+sum[rs[x]]+val[x];
        m[x]=max(max(0,rm[ls[x]])+val[x]+max(0,lm[rs[x]]),max(m[ls[x]],m[rs[x]]));
        lm[x]=max(lm[ls[x]],sum[ls[x]]+val[x]+max(0,lm[rs[x]]));
        rm[x]=max(rm[rs[x]],sum[rs[x]]+val[x]+max(0,rm[ls[x]]));
    }
    void change(int x,int v)
    {
        val[x]=v;
        sum[x]=size[x]*v;
        lm[x]=rm[x]=max(0,sum[x]);
        m[x]=max(val[x],sum[x]);
        f[x]=v;
    }
    void rotate(int x)
    {
        swap(ls[x],rs[x]);
        swap(lm[x],rm[x]);
        s[x]^=1;
    }
    void downdata(int x)
    {
        if(s[x])
        {
            if(ls[x])
            {
                rotate(ls[x]);
            }
            if(rs[x])
            {
                rotate(rs[x]);
            }
        }
        if(f[x]!=INF)
        {
            if(ls[x])
            {
                change(ls[x],f[x]);
            }
            if(rs[x])
            {
                change(rs[x],f[x]);
            }
        }
        s[x]=0;
        f[x]=INF;
    }
    int build(int l,int r)
    {
        if(l>r)
        {
            return 0;
        }
        int mid=(l+r)>>1;
        int v=a[mid];
        int x=insert(v);
        ls[x]=build(l,mid-1);
        rs[x]=build(mid+1,r);
        updata(x);
        return x;
    }
    void split(int now,int t,int &x,int &y)
    {
        if(!now)
        {
            x=y=0;
        }
        else
        {
            downdata(now);
            if(t<=size[ls[now]])
            {
                y=now;
                split(ls[now],t,x,ls[now]);
            }
            else
            {
                x=now;
                split(rs[now],t-size[ls[now]]-1,rs[now],y);
            }
            updata(now);
        }
    }
    int merge(int x,int y)
    {
        if(!x||!y)
        {
            return x+y;
        }
        downdata(x);
        downdata(y);
        if(r[x]<r[y])
        {
            rs[x]=merge(rs[x],y);
            updata(x);
            return x;
        }
        else
        {
            ls[y]=merge(x,ls[y]);
            updata(y);
            return y;
        }
    }
    void inque(int x)
    {
        if(!x)
        {
            return ;
        }
        q.push(x);
        inque(ls[x]);
        inque(rs[x]);
    }
    int main()
    {
        srand(16);
        scanf("%d%d",&n,&k);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
        }
        val[0]=m[0]=-INF;
        root=build(1,n);
        while(k--)
        {
            scanf("%s",ch);
            if(ch[0]=='I')
            {
                scanf("%d%d",&pos,&num);
                for(int i=1;i<=num;i++)
                {
                    scanf("%d",&a[i]);
                }
                z=build(1,num);
                split(root,pos,x,y);
                root=merge(merge(x,z),y);
            }
            else if(ch[0]=='D')
            {
                scanf("%d%d",&pos,&num);
                split(root,pos-1,x,y);
                split(y,num,b,c);
                root=merge(x,c);
                inque(b);
            }
            else if(ch[2]=='K')
            {
                scanf("%d%d%d",&pos,&num,&g);
                split(root,pos-1,x,y);
                split(y,num,b,c);
                change(b,g);
                root=merge(x,merge(b,c));
            }
            else if(ch[0]=='R')
            {
                scanf("%d%d",&pos,&num);
                split(root,pos-1,x,y);
                split(y,num,b,c);
                rotate(b);
                root=merge(x,merge(b,c));
            }
            else if(ch[0]=='G')
            {
                scanf("%d%d",&pos,&num);
                split(root,pos-1,x,y);
                split(y,num,b,c);
                printf("%d
    ",sum[b]);
                root=merge(x,merge(b,c));
            }
            else
            {
                printf("%d
    ",m[root]);
            }
        }
        return 0;
    }
  • 相关阅读:
    JavaScript Patterns 5.7 Object Constants
    JavaScript Patterns 5.6 Static Members
    JavaScript Patterns 5.5 Sandbox Pattern
    JavaScript Patterns 5.4 Module Pattern
    JavaScript Patterns 5.3 Private Properties and Methods
    JavaScript Patterns 5.2 Declaring Dependencies
    JavaScript Patterns 5.1 Namespace Pattern
    JavaScript Patterns 4.10 Curry
    【Android】如何快速构建Android Demo
    【Android】如何实现ButterKnife
  • 原文地址:https://www.cnblogs.com/Khada-Jhin/p/9218409.html
Copyright © 2020-2023  润新知