zoukankan      html  css  js  c++  java
  • 【fhq Treap】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

    题解

    非常恶心的一道题。。。

    用fhq Treap完成的话

    1、把原有的平衡树从pos处拆开,把新加的点新建一颗小平衡树合并进去

    2、把原有平衡树从pos和pos+num处拆开,合并左右中间不要【但是记得回收下标】

    3、把原有平衡树从pos和pos+num处拆开,在中间打上标记cov

    4、把原有平衡树从pos和pos+num处拆开,在中间打上标记mark

    5、把原有平衡树从pos和pos+num处拆开,输出sum[中间]

    6、输出ma[rt];

    【注意fhq Treap的lazy标记和线段树的不一样,线段树的标记是标而不改,fhq Treap是标时即改,不然在split和merge时可能不会改变之前标记的根节点】

    注:spli是我校大神,用函数名调戏一下他hhh

    代码

    //by 减维
    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<queue>
    #include<cstdlib>
    #include<ctime>
    #include<cmath>
    #include<map>
    #include<bitset>
    #include<algorithm>
    #define inf 1<<30
    #define ll long long
    using namespace std;
     
    int n,m,rt,sz,siz[500005],son[500005][2],val[500005],lm[500005],rm[500005],ma[500005],sum[500005],mark[500005],cov[500005],pri[500005];
    int a[200005];
    char ch[25];
    queue<int>q;
     
    int newnode(int v)
    {
        int x;
        if(!q.empty())
            x=q.front(),q.pop();
        else x=++sz;
        siz[x]=1;
        son[x][0]=son[x][1]=mark[x]=0;
        cov[x]=inf;pri[x]=rand();
        val[x]=sum[x]=ma[x]=v;
        lm[x]=rm[x]=v;
        return 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(lm[son[x][0]],sum[son[x][0]]+val[x]+max(0,lm[son[x][1]]));
        rm[x]=max(rm[son[x][1]],sum[son[x][1]]+val[x]+max(0,rm[son[x][0]]));
    }
     
    void covered(int x,int v)
    {
        val[x]=v;
        sum[x]=siz[x]*v;
        lm[x]=rm[x]=max(0,sum[x]);
        ma[x]=max(sum[x],val[x]);
        cov[x]=v;
    }
     
    void zhuan(int now)
    {
        swap(son[now][0],son[now][1]);
        swap(lm[now],rm[now]);
        mark[now]^=1;
    }
     
    void pd(int now)
    {
        if(mark[now]){
            if(son[now][0])zhuan(son[now][0]);
            if(son[now][1])zhuan(son[now][1]);
        }
        if(cov[now]!=inf){
            if(son[now][0])covered(son[now][0],cov[now]);
            if(son[now][1])covered(son[now][1],cov[now]);
        }
        mark[now]=0;cov[now]=inf;
    }
     
    int build(int l,int r)
    {
        if(l>r)return 0;
        int mid=(l+r)>>1,v=a[mid];
        int now=newnode(v);
        son[now][0]=build(l,mid-1);
        son[now][1]=build(mid+1,r);
        upda(now);
        return now;
    }
     
    void dfs(int now)
    {
        if(!now)return;
        dfs(son[now][0]);
        printf("%d ",val[now]);
        dfs(son[now][1]);
    }
     
    void spli(int now,int k,int &x,int &y)
    {
        if(!now)x=y=0;
        else{
            pd(now);
            if(k<=siz[son[now][0]])
                y=now,spli(son[now][0],k,x,son[now][0]);
            else
                x=now,spli(son[now][1],k-siz[son[now][0]]-1,son[now][1],y);
            upda(now);
        }
    }
     
    int merge(int x,int y)
    {
        if(!x||!y)return x+y;
        pd(x),pd(y);
        if(pri[x]<pri[y])
        {
            son[x][1]=merge(son[x][1],y);
            upda(x);
            return x;
        }else{
            son[y][0]=merge(x,son[y][0]);
            upda(y);
            return y;
        }
    }
     
    void rudui(int x)
    {
        if(!x)return ;
        q.push(x);
        rudui(son[x][0]);
        rudui(son[x][1]);
    }
     
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;++i)scanf("%d",&a[i]);
        sum[0]=siz[0]=mark[0]=cov[0]=0;
        ma[0]=val[0]=-inf;
        rt=build(1,n);
        int pos,num,x,y,z,k,b,c,d;
        for(int i=1;i<=m;++i)
        {
            //dfs(rt);printf("
    "); 
            scanf("%s",ch+1);
            if (ch[1]=='I'){
                scanf("%d %d",&pos,&num);
                for(int i=1;i<=num;++i)scanf("%d",&a[i]);
                z=build(1,num);
                spli(rt,pos,x,y);
                rt=merge(merge(x,z),y);
            }else if (ch[1]=='D'){
                scanf("%d%d",&pos,&num);
                spli(rt,pos-1,x,y);
                spli(y,num,b,c);
                rt=merge(x,c);
                rudui(b);//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
            }else if (ch[1]=='M' && ch[3] =='K'){
                scanf("%d%d%d",&pos,&num,&k);
                spli(rt,pos-1,x,y);
                spli(y,num,b,c);
                covered(b,k);
                rt=merge(x,merge(b,c));
            }else if (ch[1]=='R'){
                scanf("%d%d",&pos,&num);
                spli(rt,pos-1,x,y);
                spli(y,num,b,c);
                zhuan(b);
                rt=merge(x,merge(b,c));
            }else if (ch[1]=='G'){
                scanf("%d%d",&pos,&num);
                spli(rt,pos-1,x,y);
                spli(y,num,b,c);
                printf("%d
    ",sum[b]);
                rt=merge(x,merge(b,c));
            }else{
                printf("%d
    ",ma[rt]);
            }
        }
        return 0;
    }
  • 相关阅读:
    【java】对象赋值给另一个对象
    spring boot系列(五)spring boot 配置spring data jpa (查询方法)
    Spring Data JPA 查询
    Spring Data JPA 介绍
    OpenID简介
    OAUTH协议介绍
    URL encoding(URL编码)
    RESTful 介绍
    spring boot系列(四)spring boot 配置spring data jpa (保存修改删除方法)
    spring boot 启动报 java.lang.NoClassDefFoundError: ch/qos/logback/core/spi/LifeCycle 错误
  • 原文地址:https://www.cnblogs.com/rir1715/p/7880819.html
Copyright © 2011-2022 走看看