Cod sursa(job #2796376)

Utilizator PopoviciRobertPopovici Robert PopoviciRobert Data 7 noiembrie 2021 22:57:44
Problema Range minimum query Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.53 kb
#include <bits/stdc++.h>

#define Forward(x) std::forward<decltype(x)>(x)

template<typename T>
class RMQ {
public:
	RMQ(auto&& values) : values(Forward(values)) {
		n = this->values.size();
		build();
	}

	const T& query_val(int l, int r) const {
		return values[query_pos(l, r)];
	}

private:
	void build() {
		compute_log(n);

		rmq.resize(log[n] + 1, std::vector<int>(n));
		iota(rmq[0].begin(), rmq[0].end(), 0);

		for (int bit = 1; (1 << bit) <= n; bit++) {
			for (int i = 0; i + (1 << bit) <= n; i++) {
				int pos1 = rmq[bit - 1][i], pos2 = rmq[bit - 1][i + (1 << (bit - 1))];
				rmq[bit][i] = (values[pos1] < values[pos2] ? pos1 : pos2);
			}
		}
	}

	int query_pos(int l, int r) const {
		assert(l <= r);

		int bit = log[r - l + 1];

		int pos1 = rmq[bit][l], pos2 = rmq[bit][r - (1 << bit) + 1];
		
		return (values[pos1] < values[pos2] ? pos1 : pos2);
	}

	void compute_log(int n) {
		log.resize(n + 1);
		for (int i = 2; i <= n; i++) {
			log[i] = log[i >> 1] + 1;
		}
	}

private:
	int n;
	std::vector<T> values;

	std::vector<int> log;
	std::vector<std::vector<int>> rmq;
};

int main() {
	std::ifstream fin("rmq.in");
	std::ofstream fout("rmq.out");

	std::ios::sync_with_stdio(false);
	fin.tie(0), fout.tie(0);

	int n, m;
	fin >> n >> m;

	std::vector<int> values(n);
	for (auto& itr : values) {
		fin >> itr;
	}

	RMQ<int> rmq(std::move(values));

	while (m--) {
		int l, r;
		fin >> l >> r;
		l--, r--;

		fout << rmq.query_val(l, r) << "\n";
	}

	return 0;
}