Cod sursa(job #2800928)

Utilizator ad2708Dumitrescu Alexandra ad2708 Data 14 noiembrie 2021 14:26:28
Problema Range minimum query Scor 40
Compilator c-64 Status done
Runda Arhiva educationala Marime 2.58 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"


int square_root(int a)
{
	int sq_root = 1;
	while(sq_root * sq_root <= a)
		sq_root ++;
	return sq_root - 1;
}

int is_perfect_square(int a)
{
	if(square_root(a) * square_root(a) == a)
		return 1;
	return 0;
}

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);
}