zoukankan      html  css  js  c++  java
  • SP4487 GSS6

    题目大意

    给出一个由N个整数组成的序列A,你需要应用M个操作:

    • I p x p  处插入插入一个元素 x
    • D p 删除 p 处的一个元素
    • R p x 修改 p 处元素的值为 x
    • Q l r 查询一个区间[l,r]的最大子段和

    输入格式

    第一行一个数N,表示序列的长度

    第二行N个数,表示初始序列A

    第三行一个数M,表示操作的次数

    接下来的M行,每行一个操作,格式见题目描述

    输出格式

    输出若干行,每行一个整数,表示查询区间的最大子段和

    感谢@Anoxiacxy 提供的翻译

    题目描述

    Given a sequence A of N (N <= 100000) integers, you have to apply Q (Q <= 100000) operations:

    Insert, delete, replace an element, find the maximum contiguous(non empty) sum in a given interval.

    输入输出格式

    输入格式:

    The first line of the input contains an integer N.
    The following line contains N integers, representing the starting
    sequence A1..AN, (|Ai| <= 10000).

    The third line contains an integer Q. The next Q lines contains the operations in following form:

    I x y: insert element y at position x (between x - 1 and x).
    D x : delete the element at position x.
    R x y: replace element at position x with y.
    Q x y: print max{Ai + Ai+1 + .. + Aj | x <= i <= j <= y}.

    All given positions are valid, and given values are between -10000 and +10000.

    The sequence will never be empty.

    输出格式:

    For each "Q" operation, print an integer(one per line) as described above.

    输入输出样例

    输入样例#1: 
    5
    3 -4 3 -1 6
    10
    I 6 2
    Q 3 5
    R 5 -4
    Q 3 5
    D 2
    Q 1 5
    I 2 -10
    Q 1 6
    R 2 -1
    Q 1 6
    
    输出样例#1: 
    8
    3
    6
    3
    5
    

    Solution:

      某天下午和机房巨佬们比赛做这题谁最快AC,巨恶心。

      题意毫无思维难度,写一个平衡树就好了,关键是信息的维护情况贼多,在更新子树信息时要把所有的情况都考虑到,然后就比较码农了。

    代码:

    /*Code by 520 -- 10.18*/
    #include<bits/stdc++.h>
    #define il inline
    #define ll long long
    #define RE register
    #define For(i,a,b) for(RE int (i)=(a);(i)<=(b);(i)++)
    using namespace std;
    const int N=300005;
    int n,m,root,ch[N][2],rnd[N],date[N],cnt,siz[N];
    int lf[N],rf[N],maxn[N],sum[N];
    
    int gi(){
        int a=0;char x=getchar();bool f=0;
        while((x<'0'||x>'9')&&x!='-') x=getchar();
        if(x=='-') x=getchar(),f=1;
        while(x>='0'&&x<='9') a=(a<<3)+(a<<1)+(x^48),x=getchar();
        return f?-a:a;
    }
    
    il int newnode(int v){
        ++cnt;
        siz[cnt]=1,maxn[cnt]=sum[cnt]=date[cnt]=v,rnd[cnt]=rand(),lf[cnt]=rf[cnt]=max(date[cnt],0);
        return cnt;
    }
    
    il void up(int rt){
        siz[rt]=siz[ch[rt][0]]+siz[ch[rt][1]]+1;
        sum[rt]=date[rt]+sum[ch[rt][0]]+sum[ch[rt][1]];
        if(ch[rt][0]&&ch[rt][1]){
            lf[rt]=max(lf[ch[rt][0]],date[rt]+sum[ch[rt][0]]+lf[ch[rt][1]]);
            rf[rt]=max(rf[ch[rt][1]],date[rt]+sum[ch[rt][1]]+rf[ch[rt][0]]);
            maxn[rt]=max(lf[ch[rt][1]]+date[rt]+rf[ch[rt][0]],max(maxn[ch[rt][0]],maxn[ch[rt][1]]));
        }
        else if(ch[rt][0]) lf[rt]=max(max(0,lf[ch[rt][0]]),sum[ch[rt][0]]+date[rt]),rf[rt]=max(0,date[rt]+rf[ch[rt][0]]),maxn[rt]=max(maxn[ch[rt][0]],rf[ch[rt][0]]+date[rt]);
        else if(ch[rt][1]) rf[rt]=max(max(0,rf[ch[rt][1]]),date[rt]+sum[ch[rt][1]]),lf[rt]=max(0,date[rt]+lf[ch[rt][1]]),maxn[rt]=max(maxn[ch[rt][1]],date[rt]+lf[ch[rt][1]]);
        else maxn[rt]=date[rt],lf[rt]=rf[rt]=max(date[rt],0);
    
    }
    
    int merge(int x,int y){
        if(!x||!y) return x+y;
        if(rnd[x]<rnd[y]) {ch[x][1]=merge(ch[x][1],y),up(x);return x;}
        else {ch[y][0]=merge(x,ch[y][0]),up(y);return y;}
    }
    
    void split(int rt,int v,int &x,int &y){
        if(!rt) {x=y=0;return;}
        if(siz[ch[rt][0]]>=v) y=rt,split(ch[rt][0],v,x,ch[y][0]),up(y);
        else x=rt,split(ch[rt][1],v-siz[ch[rt][0]]-1,ch[x][1],y),up(x);
    }
    
    il void ins(int k,int v){
        int x,y; split(root,k-1,x,y);
        root=merge(merge(x,newnode(v)),y);
    }
    
    il void del(int k){
        int x,y,z; split(root,k-1,x,y),split(y,1,y,z);
        root=merge(x,z);
    }
    
    il void change(int k,int v){
        int x,y,z; split(root,k-1,x,y),split(y,1,y,z);
        root=merge(merge(x,newnode(v)),z);
    }
    
    il int query(int l,int r){
        int x,y,z,ans; split(root,r,x,y),split(x,l-1,x,z);
        ans=maxn[z];
        root=merge(merge(x,z),y);
        return ans;
    }
    
    int main(){
        n=gi(); char opt[2];int x,y;
        For(i,1,n) ins(i,gi());
        m=gi();
        while(m--){
            scanf("%s",opt),x=gi();
            if(opt[0]=='I') y=gi(),ins(x,y);
            else if(opt[0]=='D') del(x);
            else if(opt[0]=='R') y=gi(),change(x,y);
            else y=gi(),printf("%d
    ",query(x,y));
        }
        return 0;
    }
  • 相关阅读:
    收集的各种学习链接,方便查找
    用python调试Appium和雷电模拟器连接时出现Original error: Could not find 'adb.exe' in PATH
    App自动化测试之Appium环境安装(涉及雷电模拟器和真机)
    元素定位工具ChroPath
    Python+Selenium学习笔记19
    Python+Selenium学习笔记18
    Python+Selenium学习笔记17
    Python+Selenium学习笔记16
    Python+Selenium学习笔记14
    Python+Selenium学习笔记15
  • 原文地址:https://www.cnblogs.com/five20/p/9862116.html
Copyright © 2011-2022 走看看