1. 程式人生 > 其它 >GSS6 - Can you answer these queries VI

GSS6 - Can you answer these queries VI

GSS6 - Can you answer these queries VI

tree

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.

Input
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.

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

題目大意

在一個區間裡面求最大子段和。支援單點修改,插入刪除。

題解

序列問題還要插入刪除首先想到平衡樹(手動狗頭)
更新的思路就是用子樹的最大前後綴來更新。
特別注意子樹為空的情況,這個是大多數資料結構的邊界問題。
維護節點的最大子段和時要把自己考慮進去,左右子樹為空的情況,因為所有的維護的值都是不為空的,所以要單獨討論不取的情況。
只有一邊子樹+自己最優的情況一定要考慮進去

Code

#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define int long long
const int N = 2e5 + 11;
int n, a[N];
struct fhq{
    struct node{
        int ls, rs, key, sz, sum;
        int val, max, lmax, rmax;
    }t[N];
    int tot, RT;
    void push_up(int p){
        int ls = t[p].ls, rs = t[p].rs;
        int res = max(t[ls].max, t[rs].max);
        res = max(max(t[p].val, res), t[ls].rmax + t[p].val + t[rs].lmax);
        res = max(res, max(t[p].val + t[ls].rmax, t[p].val + t[rs].lmax));
        t[p].max = res;
        t[p].lmax = max(t[ls].lmax, max(t[ls].sum + t[p].val, t[ls].sum + t[p].val + t[rs].lmax));
        t[p].rmax = max(t[rs].rmax, max(t[rs].sum + t[p].val, t[rs].sum + t[p].val + t[ls].rmax));
        t[p].sz = t[ls].sz + t[rs].sz + 1;
        t[p].sum = t[ls].sum + t[rs].sum + t[p].val;
    }
    int merge(int x, int y){
        if(!x || !y)return x + y;
        int p;
        if(t[x].key < t[y].key){
            p = x;
            t[x].rs = merge(t[x].rs, y);
        }
        else {
            p = y;
            t[y].ls = merge(x, t[y].ls);
        }
        push_up(p);
        return p;
    }
    void split(int &x, int &y, int p, int v){
        if(!p){
            x = y = 0;
            return ;
        }
        int ls = t[p].ls, rs = t[p].rs;
        if(t[ls].sz + 1 <= v){
            x = p;
            split(t[p].rs, y, rs, v - t[ls].sz - 1);
        }
        else {
            y = p;
            split(x, t[p].ls, ls, v);
        }
        push_up(p);
    }
    int new_node(int val){
        t[++tot].val = val;
        t[tot].sum = t[tot].lmax = t[tot].rmax = t[tot].max = val;
        t[tot].key = rand();
        t[tot].sz = 1;
        return tot;
    }
    void insert(int pos, int v){
        int x, y;
        split(x, y, RT, pos);
        int z = new_node(v);
        RT = merge(x, merge(z, y));
    }
    void del(int pos){
        int x, y, z;
        split(x, y, RT, pos - 1);
        split(y, z, y, 1);
        RT = merge(x, z);
    }
    int query(int l, int r){
        int x, y, z;
        split(x, y, RT, l - 1);
        split(y, z, y, r - l + 1);
        int ans = t[y].max;
        RT = merge(x, merge(y, z));
        return ans;
    }
    void print(int p){
        if(!p)return ;
        print(t[p].ls);
        printf("p=%d val=%d max=%d ls=%d rs=%d lmax=%d rmax=%d\n", p, t[p].val, t[p].max, t[p].ls, t[p].rs, t[p].lmax, t[p].rmax);
        print(t[p].rs);
    }
    void init(){
        t[0].max = t[0].lmax = t[0].rmax = t[0].val = -1e9;
    }
}T;
int read(){
    int x = 0;
    char ch = getchar();
    while(ch > '9' || ch < '0')ch = getchar();
    while(ch >= '0' && ch <= '9')x = 10 * x + ch - 48, ch = getchar();
    return x;
}
signed main(){
    int Q;
    cin>>n;
    T.init();
    for(int i = 1;i <= n; i++){
        scanf("%lld", &a[i]);
        T.insert(i, a[i]);
    }
    //printf("max=%d\n", T.t[T.RT].max);
    cin>>Q;
    while(Q--){
        char s[11], fl;
        int x, y;
        scanf("%s", s + 1);
        fl = s[1];
        if(fl == 'I')scanf("%lld%lld", &x, &y), T.insert(x - 1, y);
        if(fl == 'D')scanf("%lld", &x), T.del(x);
        if(fl == 'R')scanf("%lld%lld", &x, &y), T.del(x), T.insert(x - 1, y);
        if(fl == 'Q')scanf("%lld%lld", &x, &y), printf("%lld\n", T.query(x, y));
        //T.print(T.RT);
        //printf("max=%d\n", T.t[T.RT].max);
    }
    return 0;
}