Cod sursa(job #2917208)

Utilizator alt_contStefan alt_cont Data 3 august 2022 19:10:02
Problema Range minimum query Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.93 kb
#include <fstream>
#include <iostream>
#define MAX 100010
using namespace std;
int log_cache[MAX];
int pow_cache[25];
	
int rmq_next[2*MAX][20];
int rmq_prev[2*MAX][20];
	
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]);
		}
	}
	
}
 
	
int rmq(int a, int b){
	int k = min_2adic(a, b);
	return max(rmq_next[a][k], rmq_prev[b][k]);
}
 
	
int main(){
	ifstream fin;
	ofstream fout;
	fin.open("rmq.in");
	fout.open("rmq.out"); 
	int m, n, a, b;
	int v[2*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);
	
	for(int i=1; i<=m; ++i){
		fin >> a >> b;
		fout << -rmq(a, b) << "\n";
	}

}