Cod sursa(job #1585453)

Utilizator dm1sevenDan Marius dm1seven Data 31 ianuarie 2016 01:22:01
Problema Range minimum query Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.01 kb
#include <iostream>
using namespace std;
#include <fstream>
#include <vector>
#include <algorithm>

namespace e_016_rmq_2_
{
	void calculate_mins_pow2(int N, int* v, vector<int>& two_pow, vector<vector<int>>& mins_pow2)
	{
		//allocate memory
		mins_pow2.resize(N + 1);
		for (int i = 1; i < N; i++) {
			int mp = (int) log2(N - i);
			mins_pow2[i].resize(mp + 1);
		}

		//initialize the mins for pow = 0
		for (int i = 1; i < N; i++) mins_pow2[i][0] = min(v[i], v[i + 1]);
		
		unsigned int mp1 = (int) log2(N - 1);
		//build 2^k
		two_pow.resize(mp1 + 1);
		two_pow[0] = 1;
		for (unsigned int k = 1; k <= mp1; k++) two_pow[k] = 2 * two_pow[k - 1];

		//calculate mins
		for (unsigned int k = 1; k <= mp1; k++) {
			for (int i = 1; i < N; i++) {
				if (k < mins_pow2[i].size()) {
					int k1 = k - 1;
					mins_pow2[i][k] = min(mins_pow2[i][k1], mins_pow2[i + two_pow[k1]][k1]);
				}
				else break;
			}
		}
	}
	

	int rmq(int x, int y, int* v, vector<vector<int>>& mins_pow2)
	{
		if (x == y) return v[x];

		int k = (int)log2(y - x);
		return min(mins_pow2[x][k], mins_pow2[y - (1 << k)][k]);
	}

	//rmq in logN
	int rmq_(int x, int y, int* v, vector<int>& two_pow, vector<vector<int>>& mins_pow2)
	{
		if (x > y) swap(x, y);

		int d = y - x;

		int k = 0;
		int min_ = v[x];
		int z = x;
		while (d != 0)
		{
			int r = d % 2;
			if (r) {
				min_ = min(min_, mins_pow2[z][k]);
				z += two_pow[k];
			}

			d >>= 1;
			k++;
		}

		return min_;
	}
}

//int e_016_rmq_2()
int main()
{
	using namespace e_016_rmq_2_;

	const int MAX_N = 100000;
	int v[MAX_N + 1];
	int N, M;

	ifstream ifs("rmq.in");
	ofstream ofs("rmq.out");
	ifs >> N >> M;
	for (int i = 1; i <= N; i++) ifs >> v[i];

	
	vector<int> two_pow;
	vector<vector<int>> mins_pow2;
	calculate_mins_pow2(N, v, two_pow, mins_pow2);

	for (int i = 1; i <= M; i++) {
		int x, y;
		ifs >> x >> y;

		ofs << rmq(x, y, v, mins_pow2) << "\n";
	}

	ofs.close();
	ifs.close();


	return 0;
}