Cod sursa(job #2796357)

Utilizator PopoviciRobertPopovici Robert PopoviciRobert Data 7 noiembrie 2021 22:35:21
Problema Range minimum query Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.21 kb
#include <fstream>
#include <iostream>
#include <algorithm>
#include <vector>

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


template<typename T,
		 typename Alloc = std::vector<T>>
class SegTree {
public:
	SegTree(auto&& values) {
		n = values.size();
		resizeTree(n);

		buildTree(0, 0, n - 1, Forward(values));
	}

	void update(int pos, auto&& values) {
		update(0, 0, n - 1, pos, Forward(values));
	}

	T query(int ql, int qr) const {
		return query(0, 0, n - 1, ql, qr);
	}


private:
	void buildTree(int node, int l, int r, auto&& values) {
		if (l == r) {
			tree[node] = Forward(values)[l];
		} else {
			int mid = (l + r) / 2;

			buildTree(2 * node + 1, l, mid, Forward(values));
			buildTree(2 * node + 2, mid + 1, r, Forward(values));

			tree[node] = combine(tree[2 * node + 1], tree[2 * node + 2]);
		}
	}

	void resizeTree(std::size_t n) {
		std::size_t size = 1;
		while (size < 2 * n) {
			size <<= 1;
		}
		tree.resize(size, INF);
	}

	T combine(const T& a, const T& b) const {
		return a < b ? a : b;	
	}

	void update(int node, int l, int r, int pos, auto&& value) {
		if (l == r) {
			tree[node] = Forward(value)[l];
		} else {
			int mid = (l + r) / 2;

			if (mid <= pos) update(2 * node + 1, l, mid, pos, Forward(value));
			else update(2 * node + 2, mid + 1, r, pos, Forward(value));

			tree[node] = combine(tree[2 * node + 1], tree[2 * node + 2]);
		}
	}

	T query(int node, int l, int r, int ql, int qr) const {
		if (ql <= l && r <= qr) {
			return tree[node];
		} else {
			int mid = (l + r) / 2;
			T answer = INF;

			if (ql <= mid) answer = combine(answer, query(2 * node + 1, l, mid, ql, qr));
			if (mid < qr) answer = combine(answer, query(2 * node + 2, mid + 1, r, ql, qr));

			return answer;
		}
	}

private:
	Alloc tree;
	std::size_t n;

	const T INF = std::numeric_limits<T>::max();
};

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

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

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

	SegTree<int> st(std::move(values));

	while (m--) {
		int l, r;
		fin >> l >> r;
		fout << st.query(l - 1, r - 1) << "\n";
	}
	

	return 0;
}