Cod sursa(job #2977303)

Utilizator Vlad_NituNitu Vlad-Petru Vlad_Nitu Data 11 februarie 2023 12:20:24
Problema Arbori de intervale Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 4.69 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)

void __print(int x) { cerr << x; }

void __print(long x) { cerr << x; }

void __print(long long x) { cerr << x; }

void __print(unsigned x) { cerr << x; }

void __print(unsigned long x) { cerr << x; }

void __print(unsigned long long x) { cerr << x; }

void __print(float x) { cerr << x; }

void __print(double x) { cerr << x; }

void __print(long double x) { cerr << x; }

void __print(char x) { cerr << '\'' << x << '\''; }

void __print(const char *x) { cerr << '\"' << x << '\"'; }

void __print(const string &x) { cerr << '\"' << x << '\"'; }

void __print(bool x) { cerr << (x ? "true" : "false"); }

template<typename T, typename V, typename W>
void __print(const std::tuple<T, V, W> &x) {
    cerr << '{';
    __print(std::get<0>(x));
    cerr << ',';
    __print(std::get<1>(x));
    cerr << ',';
    __print(std::get<2>(x));
    cerr << '}';
}

template<typename T, typename V>
void __print(const pair<T, V> &x) {
    cerr << '{';
    __print(x.first);
    cerr << ',';
    __print(x.second);
    cerr << '}';
}

template<typename T>
void __print(const T &x) {
    int f = 0;
    cerr << '{';
    for (auto &i: x) cerr << (f++ ? "," : ""), __print(i);
    cerr << "}";
}

void _print() { cerr << "]\n"; }

template<typename T, typename... V>
void _print(T t, V... v) {
    __print(t);
    if (sizeof...(v)) cerr << ", ";
    _print(v...);
}

#ifndef ONLINE_JUDGE
#define dbg(x...) cerr << "[" << #x << "] = ["; _print(x)
#else
#define dbg(x...)
#endif

struct hash_pair {
    template<class T1, class T2>
    size_t operator()(const pair<T1, T2> &p) const {
        auto hash1 = hash<T1>{}(p.first);
        auto hash2 = hash<T2>{}(p.second);

        if (hash1 != hash2) {
            return hash1 ^ hash2;
        }
        return hash1;
    }

};

struct hash_tuple {
    size_t operator()(const tuple<int, int, int> &x) const {
        return hash<long long>()(
                ((long long) std::get<1>(x) ^ (((long long) std::get<2>(x)) ^ (long long) std::get<2>(x))) << 32);
    }
};

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

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 -INT_MAX;

    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);
    }

//    cout << '\n';
//
//    for (int i = 0; i <= 10 ;++i)
//        cout << mx[i] << ' ';

    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;
}