[SP2916] Can you answer these queries V - segment tree

Face questions

You are given a sequence \(a_1,a_2,...,a_n\). (\(|A[i]| \leq 10000 , 1 \leq N \leq 10000\)). A query is defined as follows: Query(x1,y1,x2,y2) = \(Max{a_i+a_{i+1}+...+a_j;x_1 \leq i \leq y_1 , x_2 \leq j \leq y_2}\) and \(x_1 \leq x_2 , y_1 \leq y_2\). Given \(m\) queries (\(1 \leq M \leq 10000\)), your program must output the results of these queries.

The meaning of problems

All sections are required in the left and right end points \ ([x_1, y_1] \ ) and ([x_2, y_2] \) \ maximum continuous sub-segment interval and a maximum value

Thinking

1 ° two disjoint intervals


The obvious answer is left rmax + interval does not overlap the intermediate sum + lmax the right part of the section, namely: \ ([x_1, Y_1] .rmax + [Y_1, x_2] .sum + [x_2, Y_2] .lmax \)

2 ° two intersecting sections


The answer will have three cases
· ① answer to the division intersection parts, namely: \ ([x_2, Y_1] .max \)
· ② The answer left point range rmax intersection of the left part, left the intersection and take the rest lmax range, and then added to the left minus twice intersection node
namely: \ ([x_1, x_2] .rmax + [x_2, Y_2] x_2 .lmax-A_ {} \)
· ③ right answer section at the intersection point a right portion, and the remaining rmax lmax taking intersection of the right portion of the section, and then added to the right lost twice intersection node
namely: \ ([Y_1, Y_2] .lmax + [x_1, Y_1] .rmax-Y_1 A_ {} \)

Code

/************************************************
*Author        :  lrj124
*Created Time  :  2019.09.27.21:55
*Mail          :  [email protected]
*Problem       :  spoj2916
************************************************/
#include <algorithm>
#include <cstring>
#include <cstdio>
using namespace std;
const int maxn = 10000 + 10;
struct seg { int l,r,sum,max; } tree[maxn<<2];
int T,n,q,a[maxn];
inline void pushup(int root) {
    tree[root].sum = tree[root<<1].sum+tree[root<<1|1].sum;
    tree[root].l = max(tree[root<<1].l,tree[root<<1|1].l+tree[root<<1].sum);
    tree[root].r = max(tree[root<<1|1].r,tree[root<<1].r+tree[root<<1|1].sum);
    tree[root].max = max(tree[root<<1].r+tree[root<<1|1].l,max(tree[root<<1].max,tree[root<<1|1].max));
}
inline void build(int l,int r,int root) {
    if (l == r) {
        tree[root] = { a[l],a[l],a[l],a[l] };
        return;
    }
    int mid = l+r>>1;
    build(l,mid,root<<1);
    build(mid+1,r,root<<1|1);
    pushup(root);
}
inline seg query(int l,int r,int ql,int qr,int root) {
    if (ql > qr) return {0,0,0,0};
    if (ql <= l && r <= qr) return tree[root];
    int mid = l+r>>1;
    if (mid >= qr) return query(l,mid,ql,qr,root<<1);
    if (ql > mid) return query(mid+1,r,ql,qr,root<<1|1);
    seg lson = query(l,mid,ql,qr,root<<1),rson = query(mid+1,r,ql,qr,root<<1|1),ans;
    ans = { max(lson.l,rson.l+lson.sum),max(rson.r,lson.r+rson.sum),rson.sum+lson.sum,max(lson.r+rson.l,max(lson.max,rson.max)) };
    return ans;
}
inline int solve(int l1,int r1,int l2,int r2) {
    if (r1 < l2) return query(1,n,l1,r1,1).r+query(1,n,r1+1,l2-1,1).sum+query(1,n,l2,r2,1).l;
    int ans = query(1,n,l2,r1,1).max;
    if (l1 < l2) ans = max(ans,query(1,n,l1,l2,1).r+query(1,n,l2,r2,1).l-a[l2]);
    if (r2 > r1) ans = max(ans,query(1,n,l1,r1,1).r+query(1,n,r1,r2,1).l-a[r1]);
    return ans;
}
int main() {
    for (scanf("%d",&T);T--;) {
        memset(tree,0,sizeof(tree));
        scanf("%d",&n);
        for (int i = 1;i <= n;i++) scanf("%d",&a[i]);
        build(1,n,1);
        for (scanf("%d",&q);q--;) {
            int l1,r1,l2,r2; scanf("%d%d%d%d",&l1,&r1,&l2,&r2);
            printf("%d\n",solve(l1,r1,l2,r2));
        }
    }
    return 0;
}

Guess you like

Origin www.cnblogs.com/lrj124/p/11681318.html