Cod sursa(job #2977304)

Utilizator Vlad_NituNitu Vlad-Petru Vlad_Nitu Data 11 februarie 2023 12:23:55
Problema Arbori de intervale Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.63 kb
//
// Created by Vlad Nitu on 11.02.2023.
//

#include <bits/stdc++.h>

using namespace std;

#define NMAX (int)(100001)
#define INF (int)(1e9)
#define ll long long
#define mkp make_pair
#define mkt make_tuple
#define lsb(x) (x & -x)


int T, N, Q;
int lo[4 * NMAX + 1], hi[4 * NMAX + 1], mx[4 * NMAX + 1], delta[4 * NMAX + 1];

void build(int i, int a, int b) { // Initialise SegmentTree
    lo[i] = a;
    hi[i] = b;
    if (a == b)
        return;

    int mid = (a + b) / 2;
    build(2 * i, a, mid);
    build(2 * i + 1, mid + 1, b);
}

// `prop` and `update` -> template for SegmentTree that need to be modified depending on the task (min, max, sum, etc.)
int prop(int i) { // Lazy propagation of Segment Tree => push changes down to children
    delta[2 * i] += delta[i];
    delta[2 * i + 1] += delta[i];
    delta[i] = 0;
}

void update(int i) { // Aggregate update function
    mx[i] = max(mx[2 * i] + delta[2 * i], mx[2 * i + 1] + delta[2 * i + 1]);
}

void increment(int i, int a, int b, int val) {
    if (b < lo[i] || hi[i] < a) // Outside the range [a,b] I'm updating
        return;

    if (a <= lo[i] &&
        hi[i] <= b) { // [a,b] (interval I'm trying to cover) completely covers current node ([lo[i], hi[i]])
        // Completely covering the subtree
        delta[i] += val;
        return;
    }

    // Partial cover case

    prop(i); // Push change down to children before recursing

    increment(2 * i, a, b, val);
    increment(2 * i + 1, a, b, val);

    update(i); // Store aggregate maximum of the entire subtree
}

void increment(int a, int b, int val) { // UPDATE: Increment all values in range [a, b] by `val`
    increment(1, a, b, val);
}

int maximum(int i, int a, int b) {

    if (b < lo[i] || a > hi[i]) // Outside range
        return -1;

    if (a <= lo[i] && b >= hi[i]) // Entirely covering the node
        return mx[i] + delta[i];

    // Partial cover case

    prop(i);

    int maxLeft = maximum(2 * i, a, b);
    int maxRight = maximum(2 * i + 1, a, b);

    update(i);

    return max(maxLeft, maxRight);
}

int maximum(int a, int b) { // QUERY: Maximum element in range [a, b]
    return maximum(1, a, b);
}

int task, a, b, x;
int main() {

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

    cin >> N >> Q;

    build(1, 1, N);


    for (int i = 1; i <= N; ++i)
    {
        cin >> x;
        increment(i, i, x);
    }

    while (Q --) {
        cin >> task >> a >> b;

        if (task == 0) {
            cout << maximum(a, b) << '\n';
        }
        else
        {
            int cur_val = maximum(a, a);
            increment(a, a, -cur_val + b); // v[a] = b
        }

    }


    return 0;
}