Cod sursa(job #2898260)

Utilizator disinfoion ion disinfo Data 6 mai 2022 15:23:50
Problema Range minimum query Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.4 kb
#include <fstream>
#include <iostream>
#define MAX 100010
using namespace std;
int log_cache[MAX];
int pow_cache[23];

int rmq_next[MAX][19];
int rmq_prev[MAX][19];

int log2(int n){
	if(log_cache[n])
		return log_cache[n];

	if(n == 1)
		return 0;

	int counter = 0;
	while(n != 0){
		n = n >> 1;
		++counter;
	}
	return counter - 1;
}


int min_2adic(int a, int b){
	int len = log2(b - a + 1);
	int e = 2 * pow_cache[len];
	if(a % e > b % e || a % e == 0)
		return len + 1;
	else
		return len;
}

int next_2adic(int n, int k){
	if(n % pow_cache[k])
		return (n / pow_cache[k] + 1) * pow_cache[k];
	else
		return (n / pow_cache[k]) * pow_cache[k];
}

int prev_2adic(int n, int k){
	return (n / pow_cache[k]) * pow_cache[k];
}

void preprocess(int v[], int n){
	int next_r, prev_r;

	for(int i=1; i <= n; ++i)
		rmq_prev[i][0] = rmq_next[i][0] = v[i];

	for(int j=1; j <= log2(n); ++j){
		for(int i=0; i <= n; ++i){
			next_r = next_2adic(i, j - 1);
			if(next_r == next_2adic(i, j))
				rmq_next[i][j] = rmq_next[i][j - 1];
			else
				rmq_next[i][j] = max(rmq_next[i][j - 1], rmq_next[next_r + 1][j - 1]);

			prev_r = prev_2adic(i, j - 1);
			if(prev_r == prev_2adic(i, j))
				rmq_prev[i][j] = rmq_prev[i][j - 1];
			else
				rmq_prev[i][j] = max(rmq_prev[i][j - 1], rmq_prev[prev_r - 1][j - 1]);
		}
	}

	/*for(int j=0; j <= log2(n); ++j){
		for(int i=1; i <= n; ++i)
			cout << "indices: " << i << "-" << next_2adic(i, j) << ", max: " << rmq_next[i][j] << " ;\n";
		for(int i=1; i <= n; ++i)
			cout << v[i];
		cout << "\n";
	}*/
}

int rmq(int a, int b){
	int k = min_2adic(a, b);
	return max(rmq_next[a][k], rmq_prev[b][k]);
}

void debug(int v[], int n){
	cout << "========================\n";
	for(int i = 1; i <= n; ++i){
		for(int j = i + 1; j <= n; ++j)
			cout << "indices: " << i << "-" << j << ": " << rmq(i, j) << ";\n";
		for(int i=1; i <= n; ++i)
			cout << v[i];
		cout << "\n";
	}
}

int main(){
	ifstream fin;
	ofstream fout;
	fin.open("rmq.in");
	fout.open("rmq.out"); 
	int m, n, q, a, b;
	int v[MAX];

	fin >> n >> m;
	pow_cache[0] = 1;

	for(int i=1; i <= n; ++i){
		fin >> v[i];
		v[i] = -v[i];
		log_cache[i] = log2(i);
	}
	for(int i=1; i < 21; ++i){
		pow_cache[i] = 2 * pow_cache[i - 1];
	}



	preprocess(v, n);
	//debug(v, n);

	for(int i=1; i<=m; ++i){
		fin >> a >> b;
		fout << -rmq(a, b) << "\n";
	}

}