Cod sursa(job #2496406)

Utilizator NineshadowCarapcea Antonio Nineshadow Data 20 noiembrie 2019 20:17:25
Problema Range minimum query Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.86 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";
	
    }
	
 
	
}