Cod sursa(job #2800925)

Utilizator ad2708Dumitrescu Alexandra ad2708 Data 14 noiembrie 2021 14:23:50
Problema Range minimum query Scor 0
Compilator c-64 Status done
Runda Arhiva educationala Marime 2.37 kb
/*
 * Copyright 2021 - Dumitrescu Alexandra
 * grupa 323, seria CA, ACS UPB
 * Tema #1 - RMQ - Range Minimum Query
 * Noiembrie 2021
 */


#include <stdio.h>
#include <stdlib.h>
#include "./utils/utils.h"
#include "./utils/math_utils.h"

void preprocess(int N, int *v, int **preprocessed_data) {
	int block_size = square_root(N);
	int block_count = square_root(N);

	if(!is_perfect_square(N))
		block_count ++;

	(*preprocessed_data) = malloc(block_count * sizeof(**preprocessed_data));

	int block_minimum, i, j;
	for(i = 0, j = 0; i < N; i++) {
		if(i % block_size == 0) {
			if(i != 0) {
				(*preprocessed_data)[j] = block_minimum;
				j ++;
			}
			block_minimum = v[i];
		}
		if(v[i] < block_minimum)
			block_minimum = v[i];
	}

	if(!is_perfect_square(N)) 
		(*preprocessed_data)[j] = block_minimum;
}


int rmq(int left, int right, int N, int *v, int *preprocessed_data) {
	int block_size = square_root(N);
	int rmq_ans, i, j;

	left --;
	right --;

	if(left == right)
		return v[left];

	rmq_ans = v[left];
	for(i = left; i % block_size != 0 && i < right; i++) {
		if(v[i] < rmq_ans)
			rmq_ans = v[i];
	}

	for(j = i / block_size; i + block_size < right ; i+= block_size, j++) {
		if(i >= right)
			break;
		if(preprocessed_data[j] < rmq_ans)
			rmq_ans = preprocessed_data[j];
	}

	for(j = i; j <= right; j++) {
		if(v[j] < rmq_ans)
			rmq_ans = v[j];
	}

	return rmq_ans;
}


// void get_queries(int N, int *v, int *preprocessed_data) {
// 	int M, left_bound, right_bound;
// 	scanf("%d", &M);
// 	for(int nr_query = 0; nr_query < M; nr_query++) {
// 		scanf("%d %d", &left_bound, &right_bound);
// 		printf("%d\n", rmq(left_bound, right_bound, N, v, preprocessed_data));
// 	}
// }

// void get_data(int *N, int **v) {
// 	scanf("%d", N);
// 	(*v) = malloc((*N) * sizeof(**v));

// 	for(int i = 0; i < *N; i++)
// 		scanf("%d", &((*v)[i]));
// }

int main(void)
{	
	int N, M, *v = NULL, *preprocessed_data = NULL;
	// get_data(&N, &v);
	FILE *in = fopen("rmq.in", "rt");
	FILE *out = fopen("rmq.out", "wt");
	fscanf(in, "%d %d", &N, &M);
	v = malloc(N * sizeof(int));
	for(int i = 0; i < N; i++)
		fscanf(in, "%d", &v[i]);
	

	preprocess(N, v, &preprocessed_data);
	for(int i = 0; i < M; i++)
	{
		int left_b, right_b;
		fscanf(in, "%d %d", &left_b, &right_b);
		fprintf(out, "%d\n", rmq(left_b, right_b, N, v, preprocessed_data));
	}
	// get_queries(N, v, preprocessed_data);
	free(v);
	free(preprocessed_data);
}