Cod sursa(job #3265541)

Utilizator not_anduAndu Scheusan not_andu Data 31 decembrie 2024 12:18:27
Problema Arbori de intervale Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.84 kb
/*

! QUERY:
    * 0 x y - afiseaza maximul din intervalul [x, y]
    * 1 x y - valoarea elementului de pe pozitia x devine y

*/

#include <bits/stdc++.h>

using namespace std;

#define INFILE "arbint.in"
#define OUTFILE "arbint.out"

struct Node {

public:
    int value;

    Node(){}
    Node(int _value) : value(_value) {}

    // ! Elementul maxim
    friend bool operator < (const Node &a, const Node &b){
        return a.value < b.value;
    }   

    friend Node compareNodes(const Node &a, const Node &b){
        return (a < b ? b : a);
    }
};

struct SegmentTree {

private:
    int n;
    vector<Node> tree;

    int leftChild(int node){
        return (1 << node);
    }

    int rightChild(int node ){
        return (1 << node | 1);
    }

    int middleIndex(int left, int right){
        return (left + right) >> 1;
    }

    void update(int node, int left, int right, int position, Node value){
        if(left == right){
            tree[node] = value;
            return;
        }
        int middle = middleIndex(left, right);
        if(position <= middle){
            update(leftChild(node), left, middle, position, value);
        } else {
            update(rightChild(node), middle + 1, right, position, value);
        }
        tree[node] = compareNodes(tree[leftChild(node)], tree[rightChild(node)]);
    }

    Node query(int node, int left, int right, int queryLeft, int queryRight) {
        if(queryLeft <= left && right <= queryRight){
            return tree[node];
        }
        int middle = middleIndex(left, right);
        if(queryRight <= middle){
            return query(leftChild(node), left, middle, queryLeft, queryRight);
        }
        else if(queryLeft > middle) {
            return query(rightChild(node), middle + 1, right, queryLeft, queryRight);
        }
        return compareNodes(
            query(leftChild(node), left, middle, queryLeft, queryRight),
            query(rightChild(node), middle + 1, right, queryLeft, queryRight)
        );
    }

public:
    SegmentTree(){}
    SegmentTree(int _n) : n(_n) {
        tree.resize(4 * _n + 1, 0);
    }

    void update(int position, Node value){
        update(1, 1, n, position, value);
    }

    Node query(int left, int right){
        return query(1, 1, n, left, right);
    }
};

int n, queries;

void solve(){

    cin >> n >> queries;
    SegmentTree tree(n);

    for(int i = 1; i <= n; ++i){
        int aux; cin >> aux;
        tree.update(i, Node(aux));
    }

    while(queries--){
        bool type; cin >> type;
        int x, y; cin >> x >> y;
        if(!type){
            cout << tree.query(x, y).value << '\n';
        }
        else {
            tree.update(x, Node(y));
        }
    }

}

int main(){
    ios_base::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    freopen(INFILE, "r", stdin);
    freopen(OUTFILE, "w", stdout);
    solve();
    return 0;
}