Cod sursa(job #2496327)

Utilizator NineshadowCarapcea Antonio Nineshadow Data 20 noiembrie 2019 18:09:54
Problema Range minimum query Scor 30
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.63 kb
#include <bits/stdc++.h>

using namespace std;
ifstream in("rmq.in");
ofstream out("rmq.out");

#define MAX_ELEM 0xfffffff

void preprocess(const std::vector<int> input, std::vector<int>& tree, int node,
                int left, int right)
{
    // if a leaf is found
    if(left == right) {
        tree[node] = input[left - 1];
        return;
    }
    // calculate mid-point and right and left children
    int mid = left + (right - left) / 2, left_child = node << 1,
        right_child = (node << 1) + 1;

    // preprocess children
    preprocess(input, tree, left_child, left, mid);
    preprocess(input, tree, right_child, mid + 1, right);

    // update current node
    tree[node] = min(tree[left_child], tree[right_child]);
}

int query(const std::vector<int>& tree, int node, int left, int right,
    int tree_left, int tree_right)
{
    // return 0 when there is nothing to check
    if(left > right) {
        return MAX_ELEM;
    }
    
    // if the interval is found exactly
    if(left == tree_left && right == tree_right) {
        return tree[node];
    }
    
    // calculate mid-point and left and right children
    int tree_mid = tree_left + (tree_right - tree_left) / 2,
        left_child = node << 1, right_child = (node << 1) + 1;

    // query recursively to the left and to the right

    return min(
        query(tree, left_child, left, min(right, tree_mid), tree_left, tree_mid),
        query(tree, right_child, max(left, tree_mid + 1), right, tree_mid + 1, tree_right));
}

std::vector<int> rmq(const std::vector<int> &input,
                     const std::vector< std::pair<int, int> > &queries)
{
    int n = input.size(); // input size
    std::vector<int> ans; // return vector
    ans.reserve(queries.size());

    // store segment tree as balanced binary tree of size 4 * n (like a heap)
    std::vector<int> tree(n << 2);

    // build segment tree
    preprocess(input, tree, 1, 1, n);

    for(std::pair<int, int> q : queries) {
        int left = q.first, right = q.second;
        //cout << left << " " << right << ": ";
        int result = query(tree, 1, left, right, 1, n);
        //cout << result << "\n";
        ans.push_back(result);
    }

    return ans;


}

int main()
{
    int n, q;
    in >> n >> q;
    vector<int> input;
    input.reserve(n);
    vector<pair<int, int>> queries;
    queries.reserve(q);
    for(int i = 0; i < n; ++i) {
        int t;
        in >> t;
        input.push_back(t);
    }

    for(int i = 0; i < q; ++i) {
        int l, r;
        in >> l >> r;
        queries.push_back(make_pair(l, r));
    }

    vector<int> ans = rmq(input, queries);

    for(int i : ans) {
        out << i << "\n";
    }

}