"Tree line" you can answer these questions it

Given the number of columns of length N A, and M instructions, each instruction may be either of the following:

1, "1 xy", the query interval [x, y] is the maximum consecutive sub-segments and that \ (max_ x≤l≤r≤y {} \ Sigma_ I = {L} ^ of rA [I] \) .

2, "2 xy", the A [x] into y.

For each query command, output a integer answer.

Input Format

The first line of two integers N, M.

The second row of the N integers A [i].

Next, 3 M lines each integers k, x, y, k = 1 indicates that the query (in this case, if x> y, swap the x, y), k = 2 represents a modification.

Output Format

For each query command output represents an integer answer.

Each answer per line.

data range

\(N≤500000,M≤100000\)

Sample input:

5 3
1 2 -3 4 5
1 2 3
2 2 -1
1 3 2

Sample output:

2
-1

Topic Solution:

A segment tree seeking maximum range of issues and sub-segment

Very simple template ..

//#define fre yes

#include <cstdio>
#include <iostream>

const int N = 500005;
struct Node {
    int l, r;
    long long lsum, rsum, sum, mx;
} tree[N << 2];

long long ans = 0;

void updown(int k) {
    tree[k].sum = tree[k * 2].sum + tree[k * 2 + 1].sum;
    tree[k].lsum = std::max(tree[k * 2].lsum, tree[k * 2].sum + tree[k * 2 + 1].lsum);
    tree[k].rsum = std::max(tree[k * 2 + 1].rsum, tree[k * 2 + 1].sum + tree[k * 2].rsum);
    tree[k].mx = std::max(tree[k * 2].mx, tree[k * 2 + 1].mx);
    tree[k].mx = std::max(tree[k].mx, tree[k * 2].rsum + tree[k * 2 + 1].lsum);


}

void build(int k, int l, int r) {
    tree[k].l = l; tree[k].r = r;
    if(l == r) {
        scanf("%lld", &tree[k].sum);
        tree[k].lsum = tree[k].rsum = tree[k].mx = tree[k].sum;
        return ;
    }
    
    int mid = (l + r) >> 1;
    build(k * 2, l, mid);
    build(k * 2 + 1, mid + 1, r);
    updown(k);
}

void change(int k, int x, int y) {
    if(tree[k].l == tree[k].r) {
        tree[k].lsum = tree[k].rsum = tree[k].mx = tree[k].sum = y;
        return ;
    }
    
    int mid = (tree[k].l + tree[k].r) >> 1;
    if(mid >= x) change(k * 2, x, y);
    else change(k * 2 + 1, x, y);
    updown(k);
}

Node ask(int k, int l, int r) {
    if(tree[k].l >= l && tree[k].r <= r) {
        return tree[k];
    }
    
    int mid = (tree[k].l + tree[k].r) >> 1;
    if(r <= mid) return ask(k * 2, l, r);
    if(l > mid) return ask(k * 2 + 1, l, r);
    Node a, b, c;
    a = ask(k * 2, l, mid);
    b = ask(k * 2 + 1, mid + 1, r);
    c.sum = a.sum + b.sum;
    c.lsum = std::max(a.lsum, a.sum + b.lsum);
    c.rsum = std::max(b.rsum, b.sum + a.rsum);
    c.mx = std::max(a.rsum + b.lsum, std::max(a.mx, b.mx));
    return c;
}

int main() {
    static int n, m;
    scanf("%d %d", &n, &m);
    build(1, 1, n);
    for (int i = 1; i <= m; i++) {
        int x, y, z;
        scanf("%d %d %d", &x, &y, &z);
        if(x == 1) {
            ans = 0;
            if(y > z) std::swap(y, z);
            Node w = ask(1, y, z);
            printf("%lld\n", w.mx);
        }
        
        if(x == 2) {
            change(1, y, z);
        }
    } return 0;
}

Guess you like

Origin www.cnblogs.com/Nicoppa/p/11424092.html