Cod sursa(job #1446051)

Utilizator mouse_wirelessMouse Wireless mouse_wireless Data 31 mai 2015 19:40:24
Problema Range minimum query Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.82 kb
#include <cstdio>
#include <cassert>
#include <algorithm>
#define _submit
using namespace std;
#ifdef _submit
#define InFile "rmq.in"
#define OutFile "rmq.out"
#else
#define InFile "fis.in"
#define OutFile "fis.out"
#endif

#define MAXN 100010
#define MAXLOGN 20

int logtable[MAXN];
int powtable[MAXLOGN];

void populateLogTable() {
	logtable[0] = 0;
	powtable[0] = 1;
	int p = 0; int nr = 1; int nextnr = 2;
	for (int i = 1; i < MAXN; i++) {
		if (i == nextnr) {
			nr = nextnr;
			nextnr <<= 1;
			p++;
			powtable[p] = nr;
		}
		logtable[i] = p;
	}
}

int mpow(int x) {
	return powtable[x];
}

int mlog(int x) {
	return logtable[x];
}

int M, N, K;
int elem[MAXN];

class jmenseq {
public:
	int operator[](int i) {
		if (i < N)
			return elem[i];
		return elem[N - 1];
	}
} seq;

int RMQtable[MAXN][MAXLOGN];

void buildTable() {
	for (int i = 0; i < N; i++)
		RMQtable[i][0] = min(seq[i], seq[i + 1]);
	for (int j = 1; j < K; j++)
	for (int i = 0; i < N; i++) {
		int right = (i + mpow(j) < N) ? (i + mpow(j)) : (N - 1);
		int B = mpow(j - 1);
		int qresult1 = RMQtable[i][j - 1];
		int qresult2 = RMQtable[right - B][j - 1];
		RMQtable[i][j] = min(qresult1, qresult2);
	}
}

int query(int left, int right) {
	if (left == right)
		return seq[left];
	int k = mlog(right - left);
	int B = mpow(k);
	int qresult1 = RMQtable[left][k];
	int qresult2 = RMQtable[right - B][k];
	return min(qresult1, qresult2);
}

int main() {
	assert(freopen(InFile, "r", stdin));
	assert(freopen(OutFile, "w", stdout));
	populateLogTable();
	scanf("%d", &N);
	scanf("%d", &M);
	K = mlog(N) + 1;
	for (int i = 0; i < N; i++)
		scanf("%d", &elem[i]);
	buildTable();
	for (int i = 0; i < M; i++) {
		int a, b;
		scanf("%d%d", &a, &b);
		printf("%d\n", query(a - 1, b - 1));
	}
	return 0;
}