Cod sursa(job #2243600)

Utilizator cosmin.pascaruPascaru Cosmin cosmin.pascaru Data 20 septembrie 2018 22:35:25
Problema Arbori de intervale Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 2.39 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) {
            if (!(left & 1)) {
                ans = combine(ans, tree[left]);
                ++left;
            }

            if (right & 1) {
                ans = combine(ans, tree[right]);
                --right;
            }

            left = getParent(left);
            right = getParent(right);
        }
 
        return ans;
    }
     
 
private:
 
    void updateFromChildren(int node) {
        tree[node] = combine(tree[getLeftChild(node)], tree[getRightChild(node)]);
    }
 
    inline int combine(int a, int b) {
        return std::max(a, b);
    }
 
    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;
 
    std::vector<int> v;
    v.reserve(n);
 
    while (n--) {
        int x;
        std::cin >> x;
        v.push_back(x);
    }
 
    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;
}