Cod sursa(job #1982157)

Utilizator botimooMiklos Botond botimoo Data 17 mai 2017 19:29:52
Problema Range minimum query Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.34 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <cmath>

using namespace std;

ifstream fin("rmq.in");
ofstream fout("rmq.out");

int n, m;
vector<int> A;
vector<int> logs;
vector<vector<int> > M;

void preprocess() {
	int i, j;

	//initialize M for the intervals with length 1
	for (i = 0; i < n; i++)
		M[i][0] = i;

	//compute values from smaller to bigger intervals
	for (j = 1; 1 << j <= n; j++)
		for (i = 0; i + (1 << j) - 1 < n; i++) {
			int p1 = M[i][j - 1];
			int p2 = M[i + (1 << (j - 1))][j - 1];
			if (A[p1] < A[p2]) {
				M[i][j] = p1;
			}
			else {
				M[i][j] = p2;
			}
		}
}

void fillLogs() {
	logs.resize(n + 1, 0);
	for (int i = 2; i <= n; i++)
	{
		logs[i] = 1 + logs[i/2];
	}
}

int RMQ(int a, int b) {
	int k = logs[b - a + 1];
	int p1 = M[a][k];
	int p2 = M[b - (1 << k) + 1][k];
	if (A[p1] <= A[p2]) {
		return p1;
	}
	else {
		return p2;
	}
}

int main() {
	fin >> n >> m;
	int x;
	for (int i = 0; i < n; i++)
	{
		fin >> x;
		cout << x << " ";
		A.push_back(x);
	}
	cout << endl;
	M.resize(n);
	for (int i = 0; i < n; i++)
	{
		M[i].resize((int)log2(n)+1);
	}
	preprocess();
	fillLogs();

	int a, b;
	for (int i = 0; i < m; i++)
	{
		fin >> a >> b;
		--a;
		--b;
		fout << A[RMQ(a, b)] << "\n";
	}
	fin.close();
	fout.close();

	return 0;
}