Cod sursa(job #633566)

Utilizator eduEduard Gabriel Bazavan edu Data 14 noiembrie 2011 00:34:39
Problema Range minimum query Scor 40
Compilator cpp Status done
Runda Arhiva educationala Marime 3.4 kb
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>

#define MAXN 100000

#define INF 100000;

int N, M;
int A[MAXN];

void initialize(int node, int *M, int N, int b, int e) {
	if (b == e) {
		M[node] = b;
	} else {
		initialize(2*node+1, M, N, b, (b+e)/2);
		initialize(2*node+2, M, N, (b+e)/2+1, e);
		if (A[M[2*node+1]] < A[M[2*node+2]]) {
			M[node]=M[2*node+1];
		} else {
			M[node]=M[2*node+2];
		}
	}
}


int query(int node, int b, int e, int M[], int N, int i, int j) {
	int p1, p2;
	if (i > e || j < b) 
		return -1;
	if (i <= b && e <= j) 
		return M[node];
	p1 = query(2*node+1, b, (b+e)/2, M, N, i, j);
	p2 = query(2*node+2, (b+e)/2+1, e, M, N, i, j);
	
	if (p1 == -1)
		return p2;
	if (p2 == -1)
		return p1;
	if (A[p1] <= A[p2])
		return p1;
	return p2;	
}

void solve_seg_tree(int N, int Mcases) {
	
	int M[4*N+1];
	initialize(0, M, N, 0, N-1);
	/*
	for (int i = 0; i < 2*N+1; i++) {
		printf("%d ", M[i]);
	}
	*/
	int x, y;
	for (int t = 0; t < Mcases; t++) {
		scanf("%d %d\n", &x, &y);
		x--,y--;
		printf("%d\n", A[query(0, 0, N-1, M, N, x, y)]);
	}
}

void solve_st(int N, int M) {
	
	int K=0;
	int p = 1;
	while (p < N) p*=2, K++;
	int B[N][K];
	
	for (int i = 0; i < N; i++) {
		B[i][0] = i;
	}
		
	for (int j = 1; 1 << j <= N; j++) {
		for (int i = 0; i + (1 << j) - 1 < N; i++) {
			if (A[B[i][j-1]] <= A[B[i + (1 << (j-1))][j-1]]) 
				B[i][j] = B[i][j-1];
			else 
				B[i][j] = B[i + (1 << (j-1))][j-1];
		}
	}
	
	/*
	for (int i = 0; i < N; i++) {
		for (int j = 0; (1 << j) < N; j++) {
			printf("%d ", B[i][j]);
		}
		printf("\n");
	}
	*/
	
	int x, y;
	for (int t = 0; t < M; t++) {
		scanf("%d %d\n", &x, &y);
		x--,y--;
		
		int k = 1;
		while((1 << k) < (y-x+1)) k++;
		k--;
		
		int answer;
		if (A[B[x][k]] <= A[B[y-(1 << k)+1][k]])
			answer = A[B[x][k]];
		else
			answer = A[B[y-(1<<k)+1][k]];
		printf("%d\n", answer);
	}
}

void solve_simple(int *A, int N, int M) {
	int x, y;
	
	long S[1000];
	long ind[1000];
	memset(S, 100000, 1000*sizeof( long));
	memset(ind, 0, 1000*sizeof( long));
	
	int d = floor(sqrt(N));
	int splits;
	for (int s = 0, i = 0; s < N-d; s += d, i++) {
		ind[i] = s;
		ind[i+1]=N;
		splits = i+1;
	}
	
	for (int i = 0; i < splits; i++) {
		S[i] = INF;
		for (int j = ind[i]; j < ind[i+1]; j++) {
			if (S[i] > A[j]) {
				S[i] = A[j];
			}
		}
	}
	S[splits] = INF;
	
	for (int t=0; t<M; t++) {
		scanf("%d %d\n", &x, &y);
		x--,y--;
		int start, stop;
		for (int i = 0; i < splits; i++) {
			if (ind[i] > x) {
				start = i;
				break;
			}
		}
		for (int i = splits-1; i >= 0; i--) {
			if (y > ind[i]) {
				stop = i-1;
				break;
			}
		}
		
		int min = INF;
		if (stop <= start) {
			for (int i = x; i <= y; i++) {
				if (A[i] < min) {
					min = A[i];
				}
			}
		} else {
			for (int i = start; i <= stop; i++) {
				if (S[i] < min) {
					min = S[i];
				}
			}
			for (int i = x; i < ind[start+1]; i++) {
				if (A[i] < min) {
					min = A[i];
				}
			}
			for (int i = ind[stop-1]; i <= y; i++) {
				if (A[i] < min) {
					min = A[i];
				}
			}
		}
		printf("%d\n", min);
	}
}



int main() {
	
	freopen("rmq.in", "rt", stdin);
	freopen("rmq.out", "wt", stdout);
	
	scanf("%d %d\n", &N, &M);
	for (int i = 0; i < N; i++) {
		scanf("%d\n", &A[i]); 
	}
	
	solve_seg_tree(N, M);
	return 0;
}