zoukankan      html  css  js  c++  java
  • 【Splay】bzoj1500(听说此题多码上几遍就能不惧任何平衡树题)

    1500: [NOI2005]维修数列

    Time Limit: 10 Sec  Memory Limit: 64 MB
    Submit: 15112  Solved: 4996
    [Submit][Status][Discuss]

    Description

    Input

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

    Output

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

    Sample Input

    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

    Sample Output

    -1
    10
    1
    10

    HINT

    题解

    用Splay进行区间操作的话,就要先把区间的l-1的位置旋转到根,再把r+1旋转成根的子节点

    然后r+1的左子树即为所求区间

    代码

    //by 减维
    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<queue>
    #include<cstdlib>
    #include<ctime>
    #include<cmath>
    #include<map>
    #include<bitset>
    #include<algorithm>
    #define ll long long
    #define maxn 500005
    #define ls son[x][0]
    #define rs son[x][1]
    #define inf 1<<29
    using namespace std;
    
    int n,m,rt,sz,siz[maxn],son[maxn][2],val[maxn],lm[maxn],rm[maxn],ma[maxn],sum[maxn];
    int a[maxn],fa[maxn],cov[maxn],mark[maxn];
    char ch[25];
    queue<int>q;
    
    bool pd(int x){return son[fa[x]][1]==x;}
    
    void upda(int x)
    {
        if(!x)return ;
        siz[x]=siz[son[x][0]]+siz[son[x][1]]+1;
        sum[x]=sum[son[x][0]]+sum[son[x][1]]+val[x];
        ma[x]=max(max(0,rm[son[x][0]])+val[x]+max(0,lm[son[x][1]]),max(ma[son[x][0]],ma[son[x][1]]));
        lm[x]=max(sum[son[x][0]]+val[x]+max(0,lm[son[x][1]]),lm[son[x][0]]);
        rm[x]=max(sum[son[x][1]]+val[x]+max(0,rm[son[x][0]]),rm[son[x][1]]);
    }
    
    int newnode(int v)
    {
        int s;
        if(!q.empty())
            s=q.front(),q.pop();
        else
            s=++sz;
        siz[s]=1;son[s][0]=son[s][1]=fa[s]=mark[s]=0;
        val[s]=sum[s]=ma[s]=lm[s]=rm[s]=v;
        cov[s]=-inf;
        return s;
    }
    
    void rotate(int x)
    {
        int f=fa[x],g=fa[f],o=pd(x);
        if(g)son[g][pd(f)]=x;
        fa[x]=g;
        son[f][o]=son[x][!o];
        fa[son[f][o]]=f;
        fa[f]=x;son[x][!o]=f;
        upda(f);upda(x);
    }
    
    void splay(int x,int tar)
    {
        for(;fa[x]!=tar;rotate(x))
            if(fa[fa[x]]!=tar)rotate(pd(fa[x])==pd(x)?fa[x]:x);
        if(tar==0)rt=x;
    }
    
    int build(int l,int r)
    {
        if(l>r)return 0;
        int mid=(l+r)>>1;
        int v=a[mid];
        int now=newnode(v);
        son[now][0]=build(l,mid-1);
        son[now][1]=build(mid+1,r);
        if(son[now][0])fa[son[now][0]]=now;
        if(son[now][1])fa[son[now][1]]=now;
        upda(now);
        return now;
    }
    
    void cover(int x,int v)
    {
        if(!x)return ;
        cov[x]=val[x]=v;
        sum[x]=v*siz[x];
        lm[x]=rm[x]=ma[x]=max(v,sum[x]);
    }
    
    void rever(int x)
    {
        if(!x)return ;
        mark[x]^=1;
        swap(son[x][0],son[x][1]);
        swap(lm[x],rm[x]);
    }
    
    void pud(int x)
    {
        if(!x)return ;
        if(mark[x]){
            if(son[x][0])rever(son[x][0]);
            if(son[x][1])rever(son[x][1]);
            mark[x]=0;
        }
        if(cov[x]!=-inf){
            if(son[x][0])cover(son[x][0],cov[x]);
            if(son[x][1])cover(son[x][1],cov[x]);
            cov[x]=-inf;
        }
    }
    
    int kth(int k)
    {
        int x=rt;
        while(1)
        {
            pud(x);
            if(k<=siz[son[x][0]])
                x=son[x][0];
            else if(k==siz[son[x][0]]+1)
                return x;
            else
                k-=siz[son[x][0]]+1,x=son[x][1];
        }
    }
    
    void ins()
    {
        int pos,num;
        scanf("%d%d",&pos,&num);
        int l=kth(pos+1),r=kth(pos+2);
        splay(l,0);
        splay(r,l);
        for(int i=1;i<=num;++i)scanf("%d",&a[i]);
        int z=build(1,num);
        fa[z]=r;
        son[r][0]=z;
        upda(z),upda(r),upda(l);
    }
    
    void delt(int &x)
    {
        if(!x)return ;
        q.push(x);
        delt(son[x][0]);
        delt(son[x][1]);
        x=0;
    }
    
    void del()
    {
        int pos,num;
        scanf("%d%d",&pos,&num);
        int l=kth(pos),r=kth(pos+num+1);
        splay(l,0);splay(r,l);
        delt(son[r][0]);
        upda(r),upda(l);
    }
    
    void change()
    {
        int pos,num,v;
        scanf("%d%d%d",&pos,&num,&v);
        int l=kth(pos),r=kth(pos+num+1);
        splay(l,0);splay(r,l);
        cover(son[r][0],v);
        upda(r),upda(l);
    }
    
    void rev()
    {
        int pos,num;
        scanf("%d%d",&pos,&num);
        int l=kth(pos),r=kth(pos+num+1);
        splay(l,0);splay(r,l);
        rever(son[r][0]);
        upda(r),upda(l);
    }
    
    void gsum()
    {
        int pos,num;
        scanf("%d%d",&pos,&num);
        int l=kth(pos),r=kth(pos+num+1);
        splay(l,0);splay(r,l);
        printf("%d
    ",sum[son[r][0]]);
    }
    
    void dfs(int x)
    {
        if(!x)return ;
        pud(x);
        dfs(son[x][0]);
        printf("%d ",ma[x]);
        dfs(son[x][1]);
    }
    
    void dfs2(int x)
    {
        if(!x)return ;
        pud(x);
        dfs2(son[x][0]);
        printf("%d ",val[x]);
        dfs2(son[x][1]);
    }
    
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=2;i<=n+1;++i)scanf("%d",&a[i]);a[1]=a[n+2]=-inf;
        siz[0]=mark[0]=fa[0]=son[0][0]=son[0][1]=0;
        val[0]=ma[0]=lm[0]=rm[0]=-inf;
        rt=build(1,n+2);
        for(int i=1;i<=m;++i)
        {
            scanf("%s",ch);
            if(ch[0]=='M'&&ch[2]=='X'){
                printf("%d
    ",ma[rt]);
                continue;
            }
            switch(ch[0]){
                case 'I':ins();break;
                case 'D':del();break;
                case 'M':change();break;
                case 'R':rev();break;
                case 'G':gsum();break;
            }
        }
        return 0;
    }
  • 相关阅读:
    java.sql.SQLException: Value '0000-00-00 00:00:00' can not be represented as java.sql.Date
    权限控制-JS判断是否有权限进行操作跳转页面需要加target
    为你的网站装个“头像”
    本地存储由来的背景
    HTML5的新的结构元素介绍
    Canvas绘图API
    HTML5文件操作API
    认识HTML5
    基于scrapy爬虫的天气数据采集(python)
    Python strip()方法
  • 原文地址:https://www.cnblogs.com/rir1715/p/7905518.html
Copyright © 2011-2022 走看看