Cod sursa(job #3185820)

Utilizator Xutzu358Ignat Alex Xutzu358 Data 20 decembrie 2023 16:14:22
Problema Range minimum query Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.18 kb
#include <fstream>
using namespace std;
ifstream f("rmq.in");
ofstream g("rmq.out");
/// Arbori de intervale - complexitate O(log n) per query 
/// RMQ - putem folosi cand nu avem update-uri, cand intervalele se pot intersecta fara sa incurce
/// rezultatul si avem O(1) per query, O(n log n) la constructie

int n, m, x, y, l;
int k[100005], kcurent;
int rmq[100005][25]; /// rmq[n][log n]
int v[100005];

void create_rmq() {
	for (int j = 0; (1 << j) <= n; j++) {
		for (int i = 1; i + (1 << j) - 1 <= n; i++) {
			if (j == 0) {
				rmq[i][j] = v[i];
			}
			else {
				rmq[i][j] = min(rmq[i][j - 1], rmq[i + (1 << (j - 1))][j - 1]);
			}
		}
	}
}

void solve() {
	/// precalculam pentru fiecare lungime posibila de interval (de la 1 la n)
	/// care este cel mai mare k, astfel incat 2^k < lungime
	for (int i = 2; i <= n; i++) {
		k[i] = k[i - 1];
		if ((1 << (k[i] + 1)) < i) {
			k[i]++;
		}
	}
	for (int t = 1; t <= m; t++) {
		f >> x >> y;
		l = y - x + 1; /// lungimea intervalului
		g << min(rmq[x][k[l]], rmq[y-(1<<k[l])+1][k[l]]) << '\n';
	}
}

int main()
{
	f >> n >> m;
	for (int i = 1; i <= n; i++) {
		f >> v[i];
	}
	create_rmq();
	solve();
}