Cod sursa(job #1093842)

Utilizator cdt2014Cont de Teste cdt2014 Data 28 ianuarie 2014 17:49:02
Problema Range minimum query Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 1.96 kb
#include <algorithm>
#include <fstream>
#include <iostream>
#include <iterator>
#include <vector>
using namespace std;

class RMQ {
	public:
		RMQ(vector<int>& elements) {
			buildLogTable(elements.size());
			buildRMQTable(elements);
		}

		int query(int low, int high) {
			int N = high-low + 1;
			int m = 0x7fffffff;
			for (int i=low, l=log[N]; i<=high && l>=0; --l) {
#ifdef __DEBUG__
				cout << l << " " << i << " ";
#endif
				if (i + (1 << l) - 1 <= high) {
#ifdef __DEBUG__
					cout << table[l][i];
#endif
					m = min(m, table[l][i]);
					i += (1 << l) ;
				}
				cout << "." << endl;
			}
#ifdef __DEBUG__
			cout << ".." << endl;
#endif
			return m;
		}

	private:
		vector<vector<int> > table;
		vector<int> log;

		void buildLogTable(int N) {
			log.push_back(0);
			for (int v=1, l=0; v<=N; ++l) {
				int p = v*2;
				for (; v<p && v<=N; ++v) {
					log.push_back(l);
				}
			}
#ifdef __DEBUG__
			cout << "done buildLogTable: ";
			ostream_iterator<int> out_it(cout, " ");
			copy(log.begin(), log.end(), out_it);
			cout << endl;
#endif
		}

		void buildRMQTable(vector<int>& values) {
			table.resize(log[values.size()] + 1);
			table[0].resize(values.size());
			copy(values.begin(), values.end(), table[0].begin());

#ifdef __DEBUG__
			for (size_t i=0; i<table[0].size(); ++i)
				cout << table[0][i] << " ";
			cout << endl;
#endif

			int d = 1;
			for (size_t l=1; l<table.size(); ++l, d*=2) {
				for (size_t i=0; i+2*d-1<values.size(); ++i) {
					table[l].push_back(min(table[l-1][i], table[l-1][i+d]));
#ifdef __DEBUG__
					cout << table[l][i] << " ";
#endif
				}
#ifdef __DEBUG__
				cout << endl;
#endif
			}
#ifdef __DEBUG__
		cout << "=======================" << endl;
#endif
		}

};

int main() {
	vector<int> V;
	ifstream in("rmq.in");
	ofstream out("rmq.out");

	int N, M;
	in >> N >> M;
	for (int i=0;i<N; ++i) {
		int x;
		in >> x;
		V.push_back(x);
	}

	RMQ rmq(V);
	while (M--) {
		int l, h;
		in >> l >> h;
		out << rmq.query(l-1, h-1) << "\n";
	}
	return 0;
}