Cod sursa(job #2243599)

Utilizator cosmin.pascaruPascaru Cosmin cosmin.pascaru Data 20 septembrie 2018 22:26:50
Problema Arbori de intervale Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.33 kb
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <vector>
#include <array>
#include <algorithm>
#include <vector>
#include <stack>
#include <assert.h>
   
using LL = long long;
using ULL = int long long;
   
const std::string _problemName = "arbint";
   
namespace std {
    std::ifstream fin(_problemName + ".in"); 
    std::ofstream fout(_problemName + ".out"); 
}
   
#define cin fin
#define cout fout
 
class SegmentTree {
 
public:
    SegmentTree(const std::vector<int>& v) {
        arraySize = v.size();
 
        tree.resize(2 * arraySize);
        std::copy(v.begin(), v.end(), tree.begin() + arraySize);
         
        for (int node = arraySize - 1; node >= 0; --node) {
            updateFromChildren(node);
        }
    }
 
    void update(int pos, int newVal) {
        pos += arraySize;
 
        tree[pos] = newVal;
 
        while (pos > 0) {
            pos = getParent(pos);
            updateFromChildren(pos);
        }
    }
 
    int query(int left, int right) {
        int ans = 0;
 
        left += arraySize;
        right += arraySize;
 
        while (left <= right) {
            ans = std::max(ans, tree[left]);
            ans = std::max(ans, tree[right]);
 
            left = getParent(left + 1);
            right = getParent(right - 1);
        }
 
        return ans;
    }
     
 
private:
 
    void updateFromChildren(int node) {
        tree[node] = std::max(tree[getLeftChild(node)], tree[getRightChild(node)]);
    }
 
    // inline int getSibling(int node) {
    //     return (node & 1) ? (node + 1) : (node - 1);
    // }
 
    inline int getParent(int node) {
        return (node - 1) / 2;
    }
 
    inline int getLeftChild(int node) {
        return 2 * node + 1;
    }
    inline int getRightChild(int node) {
        return 2 * node + 2;
    }
 
    int arraySize;
    std::vector<int> tree;
};
 
int main() {
 
    int n, m;
    std::cin >> n >> m;
 
    int sz = 1;
    while (sz < n) {
        sz *= 2;
    }

    std::vector<int> v;
    v.resize(sz);
 
    for (int i = 0; i < n; ++i) {
        std::cin >> v[i];
    }
 
    SegmentTree segTree(v);
 
    while (m--) {
        int op, a, b;
        std::cin >> op >> a >> b;
 
        if (op == 0) {
            std::cout << segTree.query(a - 1, b - 1) << '\n';
        }
        else {
            segTree.update(a - 1, b);
        }
    }
 
    return 0;
}