Cod sursa(job #2501564)

Utilizator razvanlgu31Razvan Lungu razvanlgu31 Data 29 noiembrie 2019 21:12:35
Problema Range minimum query Scor 20
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.11 kb
// #include "algo.h"
#include <vector>
#include <iostream>
#include <fstream>
#include <string>
#include <math.h>
#include <limits.h>


void read(const std::string& inFilePath, std::vector<int>& input, 
		std::vector< std::pair<int, int> >& queries) {
	// Open the file stream
	std::ifstream inFile(inFilePath);

	if (inFile.is_open()) {
		int noElements = 0;
		inFile >> noElements;

		int noQueries = 0;
		inFile >> noQueries;

		for (int i = 0; i < noElements; i++) {
			int elem;
			inFile >> elem;
			input.push_back(elem);
		}

		for (int i = 0; i < noQueries; i++) {
			int left;
			int right;
			inFile >> left >> right;
			queries.push_back({left, right});
		}
		inFile.close();
	} else {
		std::cout << "ERROR: Unable to open file!\n";
	}
}


void printResult(const std::vector<int>& results,
				const std::string& outFilePath) {
	// Open the file stream
	std::ofstream outFile(outFilePath);

	if (outFile.is_open()) {
		for (int i = 0; i < results.size(); i++) {
			// For each query print the result on a different line.
			outFile << results[i] << '\n';
		}

		outFile.close();
	} else {
		std::cout << "ERROR: Unable to open file!\n";
	}
}

// Updates the node of a given segment tree
void update(int node, int left, int right, int pos,
                int value, std::vector<int>& segTree) {
    if (left == right) {
        segTree[node] = value;
    } else {
        int mid = left +  (right - left) / 2;
 
        if (pos <= mid) {
            update(2 * node, left, mid, pos, value, segTree);
        } else {
            update(2 * node + 1, mid + 1, right, pos, value, segTree);
        }

        segTree[node] = std::min(segTree[2 * node], segTree[2 * node + 1]);
    }
 
}

// Query for a segment tree on interval [start, end]
void query(int node, int left, int right, int start, int end,
                        int &minVal,  std::vector<int> segTree) {
    if (start <= left && right <= end) {
        minVal = std::min(minVal, segTree[node]);
    } else {
        int mid =left + (right - left) / 2;

        if (start <= mid) {
            query(2 * node, left, mid, start, end, minVal, segTree);
        }

        if (end > mid) {
            query(2 * node + 1, mid + 1, right, start, end, minVal, segTree);
        }
    }
}

std::vector<int> rmq(const std::vector<int>& input,
	const std::vector< std::pair<int, int> >& queries) {
    std::vector<int> results;
    int noElements = input.size();

    std::vector<int> segTree(3 * noElements, INT_MAX);

    for (int i = 0; i < noElements; i++) {
        update(1, 1, noElements, i + 1, input[i], segTree);
    }

    // Get the result of queries
    int noQueries = queries.size();
    for (int i = 0; i < noQueries; i++) {
    	int minElem = INT_MAX;

    	int start = queries[i].first;
    	int end = queries[i].second;

        query(1, 1, noElements, start, end, minElem, segTree);

    	results.push_back(minElem);
    }

    return results;
}

int main(int argc, char const *argv[])
{
	std::vector<int> input;

	std::vector< std::pair<int, int> > queries;

	read("rmq.in", input, queries);

	std::vector<int> results;
	results = rmq(input, queries);
	printResult(results, "rmq.out");
	return 0;
}