Cod sursa(job #1983917)

Utilizator borcanirobertBorcani Robert borcanirobert Data 22 mai 2017 20:18:30
Problema Range minimum query Scor 20
Compilator cpp Status done
Runda Arhiva educationala Marime 1.4 kb
// Borcani Robert Raul
/*	In aceasta solutie folosesc o matrice
 * 	D[i][j] = minimul din intervalul i, i + 1, i + 2, ... , i + 2^j - 1
 * 
 * 	Relatia de recurenta : M[i][j] = min( M[i][j - 1], M[i + (1 << (j - 1))][j - 1] );
 * */
#include <fstream>
#include <iostream>
#include <cmath>
#include <vector>
using namespace std;

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

int N, Q;
vector<int> a;
vector< vector<int> > M;

void Read();
void Precalculate();
void AnswerQuery( int x, int y );

int main()
{
	Read();
	Precalculate();
	
	//cin.get();
	int x, y;
	while ( Q-- )
	{
		fin >> x >> y;
		AnswerQuery(x - 1, y - 1);
	}
	
	fin.close();
	fout.close();
	return 0;
}


void Read()
{
	int x;
	fin >> N >> Q;
	for ( int i = 1; i <= N; ++i )
	{
		fin >> x;
		a.push_back(x);
	}
}

void Precalculate()
{
	int i{0}, j;
	while ( (1 << i) < N )
		++i;
	M = vector< vector<int> >(N, vector<int>(i));
	for ( i = 0; i < N; ++i )
		M[i][0] = i;
	for ( j = 1; ( 1 << j ) <= N; ++j )
		for ( i = 0; i + ( 1 << j ) - 1 < N; ++i )
		{
			if ( a[M[i][j - 1]] < a[M[i + (1 << (j - 1))][j - 1]] )
				M[i][j] = M[i][j - 1];
			else
				M[i][j] = M[i + (1 << (j - 1))][j - 1];
		//	cout << i << ' ' << j << ' ' << a[M[i][j]]; cin.get();
		}
}

void AnswerQuery( int x, int y )
{
	int b{0};
	while ( x + (1 << b) <= y )
		++b;
	--b;
		
	//cout << x << ' ' << y << ' ' << b; cin.get();
	fout << min(a[M[x][b]], a[M[y - (1 << b) + 1][b]]) << '\n';
}