Cod sursa(job #1446041)

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

#define MAXN 100010
#define MAXLOGN 20

class Math {
private:
	static int logtable[MAXN];
	static int powtable[MAXLOGN];
public:
	static 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;
		}
	}
	static int pow(int x) {
		return powtable[x];
	}
	static int log(int x) {
		return logtable[x];
	}
};

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

int M;
int elem[MAXN];

class jmenseq {
private:
	int sz;
public:
	jmenseq() {
		scanf("%d", &sz);
		scanf("%d", &M);
		for (int i = 0; i < sz; i++)
			scanf("%d", &elem[i]);
	}
	int size() {
		return sz;
	}
	int operator[](int i) {
		if (i < sz)
			return elem[i];
		return elem[sz - 1];
	}
};

int container[MAXN][MAXLOGN];


class RMQtable {
private:
	int nrQ;
	RMQtable();
public:
	RMQtable(jmenseq &seq) {
		int N = seq.size();
		int K = Math::log(N) + 1;
		for (int i = 0; i < N; i++)
			container[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 + Math::pow(j) < N) ? (i + Math::pow(j)) : (N - 1);
			int B = Math::pow(j - 1);
			int qresult1 = container[i][j - 1];
			int qresult2 = container[right - B][j - 1];
			container[i][j] = min(qresult1, qresult2);
		}
	}

	int query(int left, int right, jmenseq &seq) {
		if (left == right)
			return seq[left];
		int k = Math::log(right - left);
		int B = Math::pow(k);
		int qresult1 = container[left][k];
		int qresult2 = container[right - B][k];
		return min(qresult1, qresult2);
	}

	void print(jmenseq &seq) {
		int N = seq.size();
		int K = Math::log(N);
		for (int i = 0; i < N; i++) {
			for (int j = 0; j < K; j++)
				fprintf(stderr, "%d ", container[i][j]);
			fprintf(stderr, "\n");
		}
	}
};

int main() {
	assert(freopen(InFile, "r", stdin));
	assert(freopen(OutFile, "w", stdout));
	Math::populateLogTable();
	jmenseq seq;
	RMQtable table(seq);
	table.print(seq);
	for (int i = 0; i < M; i++) {
		int a, b;
		scanf("%d%d", &a, &b);
		printf("%d\n", table.query(a - 1, b - 1, seq));
	}
	return 0;
}