Cod sursa(job #1559647)

Utilizator StarGold2Emanuel Nrx StarGold2 Data 31 decembrie 2015 13:16:30
Problema Arbori de intervale Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.09 kb
#include <cstdio>
#include <algorithm>

const int DIM = 131072;
const int INF = 0x3f3f3f3f;
using namespace std;

struct segtree {int value, lazy;} SegTree[DIM * 4];
int N, M, K, X, Y, Array[DIM];

void build (int node, int left, int right) {

    if (left == right)
        SegTree[node].value = Array[left];
    else {

        int middle = left + (right - left) / 2;

        build (  node * 2  ,    left   , middle);
        build (node * 2 + 1, middle + 1,  right);

        SegTree[node].value = max (SegTree[node * 2].value, SegTree[node * 2 + 1].value);
    }

    return;
}

void update (int node, int left, int right, int start, int finish, int value) {

    if (SegTree[node].lazy != 0) {
        SegTree[node].value += SegTree[node].lazy;

        if (left != right) {
            SegTree[  node * 2  ].lazy += SegTree[node].lazy;
            SegTree[node * 2 + 1].lazy += SegTree[node].lazy;
        }

        SegTree[node].lazy = 0;
    }

    if (start <= left && right <= finish) {
        SegTree[node].value += value;

        if (left != right) {
            SegTree[  node * 2  ].lazy += value;
            SegTree[node * 2 + 1].lazy += value;
        }

        return;

    } else {

        int middle = left + (right - left) / 2;

        if (start <= middle)
            update (  node * 2  ,    left   , middle, start, finish, value);

        if (middle < finish)
            update (node * 2 + 1, middle + 1,  right, start, finish, value);

        SegTree[node].value = max (SegTree[node * 2].value, SegTree[node * 2 + 1].value);
    }

    return;
}

int query (int node, int left, int right, int start, int finish) {

    if (SegTree[node].lazy != 0) {
        SegTree[node].value += SegTree[node].lazy;

        if (left != right) {
            SegTree[  node * 2  ].lazy += SegTree[node].lazy;
            SegTree[node * 2 + 1].lazy += SegTree[node].lazy;
        }

        SegTree[node].lazy = 0;
    }

    if (start <= left && right <= finish) {

        return SegTree[node].value;
    }
    else {

        int middle = left + (right - left) / 2;
        int value1 = -INF, value2 = -INF;

        if (start <= middle)
            value1 = query (  node * 2  ,    left   , middle, start, finish);

        if (middle < finish)
            value2 = query (node * 2 + 1, middle + 1,  right, start, finish);

        return max (value1, value2);
    }

}

int main () {

    freopen ("arbint.in" ,"r", stdin );
    freopen ("arbint.out","w", stdout);

    scanf ("%d %d", &N, &M);

    for (int i = 0; i < N; i ++)
        scanf ("%d", &Array[i]);

    build (1, 0, N-1);

    for (int i = 0; i < M; i ++) {
        scanf ("%d %d %d", &K, &X, &Y);

        switch (K) {
            case 0: {
                printf ("%d\n", query (1, 0, N - 1, X - 1, Y - 1));

                break;
            }

            case 1: {
                update (1, 0, N-1, X - 1, X - 1, Y - Array[X - 1]);
                Array[X - 1] = Y;

                break;
            }
        }
    }

    return 0;
}