Geeks - Range Minimum Query RMQ范围最小值查询

使用线段树预处理,可以使得查询RMQ时间效率在O(lgn)。

线段树是记录某范围内的最小值。

标准的线段树应用。

Geeks上只有两道线段树的题目了,而且没有讲到pushUp和pushDown操作,只是线段树的入门了。

参考:http://www.geeksforgeeks.org/segment-tree-set-1-range-minimum-query/

我修改了一下他的程序,使用pushUp操作,其实也是很简单的一个小函数。而且手动计算了下,觉得他的动态分配内存,计算需要的树的大小,这样做好像也省不了多少内存。

不过方法不错,可以学习下。

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <limits.h>

inline int LC(int rt) { return rt<<1; }
inline int RC(int rt) { return rt<<1|1; }
inline int minV(int x, int y) { return x < y ? x : y; }

inline void pushUp(int *segTree, int rt)
{
	segTree[rt] = minV(segTree[LC(rt)], segTree[RC(rt)]);
}

int RMQUtil(int *segTree, int qs, int qe, int l, int r, int rt)
{
	if (qs <= l && r <= qe)
		return segTree[rt];
	int res = INT_MAX;
	int m = l + ((r-l)>>1);	//写错没提示:l + ((r-l)>1)
	if (qs <= m) res = RMQUtil(segTree, qs, qe, l, m, LC(rt));
	if (m < qe) res = minV(RMQUtil(segTree, qs, qe, m+1, r, RC(rt)), res);
	return res;
}

int RMQ(int *segTree, int n, int qs, int qe)
{
	// Check for erroneous input values
	if (qs < 1 || qe > n || qs > qe)
	{
		puts("Invalid Input");
		return -1;
	}
	return RMQUtil(segTree, qs, qe, 1, n, 1);
}

void constructSTUtil(int arr[], int l, int r, int *segTree, int rt)
{
	if (l == r)
	{
		segTree[rt] = arr[l];
		return ;
	}
	int m = l + ((r-l)>>1);
	constructSTUtil(arr, l, m, segTree, LC(rt));
	constructSTUtil(arr, m+1, r, segTree, RC(rt));
	pushUp(segTree, rt);
}

int *constructST(int arr[], int n)
{
	int h = (int)(ceil(log((double)n)/log((double)2))) + 1;
	int treeSize = (1 << h);//1024需要开2048数组, 比一般开3倍或者4被数组省不了太多内存,因为1025就需要开4倍了,一般开3被可以,开4倍就肯定不会超内存了
	int *segTree = (int *) malloc(treeSize * sizeof(int));
	constructSTUtil(arr, 1, n, segTree, 1); //从1开始构建
	return segTree;
}

int main()
{
	int arr[] = {0, 1, 3, 2, 7, 9, 11};//0位置不使用
	int n = sizeof(arr)/sizeof(arr[0]);

	// Build segment tree from given array
	int *st = constructST(arr, n);

	int qs = 2;  // Starting from 1
	int qe = 6;  

	// Print minimum value in arr[qs..qe]
	printf("Minimum of values in range [%d, %d] is = %d\n",
		qs, qe, RMQ(st, n, qs, qe));

	free(st);
	return 0;
}

Geeks - Range Minimum Query RMQ范围最小值查询,布布扣,bubuko.com

时间: 2024-10-13 04:56:54

Geeks - Range Minimum Query RMQ范围最小值查询的相关文章

AOJ DSL_2_A Range Minimum Query (RMQ)

Range Minimum Query (RMQ) Write a program which manipulates a sequence A = {a0,a1,...,an−1} with the following operations: find(s,t): report the mimimum element in as,as+1,...,at. update(i,x): change ai to x. Note that the initial values of ai (i=0,1

范围最小值问题(Range Minimum Query,RMQ)

问题描述 给定一个n个元素的序列{A1,A2,--,An},在要求的区间Query(L,R)内找到最小值:min{AL,AL+1,--,AR}.hiho16 算法描述 在这里介绍最常用的Tarjan的Sparse-Table算法,它的预处理时间复杂度为O(nlogn),而查询时间只需要O(1).令calc(i,j)表示从i开始的,长度为2j 的一段子序列的最小值,则使用循环的方式计算:calc[i][j] = min(calc[i][j-1],calc[i+2j-1)][j-1]),代码如下:

Segment Tree Range Minimum Query.

int rangeMinQuery(int segTree[], int qlow, int qhigh, int low, int high, int pos) { if (qlow <= low && qhigh >= high) return segTree[pos]; if (qlow > high || qhigh < low) return maxVal; int mid = (low + high) / 2; return min(rangeMinQu

2-D range sum query implementation(2-D segment tree)

Google interview question:一个二维数组,有两个方法,一个是update(x,y),更新一个cell的值,一个是query(x1,y1,x2,y2),查询(x1,y1,x2,y2)矩形内所有元素的和. Senario 1. update调用次数远大于query. Senario 2. query调用次数远大于update. Senario 3. 两种方法调用一样多. 对于senario 1,只需要用一个二维数组储存数据,update相应的cell,时间复杂度O(1),qu

[LeetCode] Range Sum Query 2D - Mutable 二维区域和检索 - 可变

Given a 2D matrix matrix, find the sum of the elements inside the rectangle defined by its upper left corner (row1, col1) and lower right corner (row2, col2). The above rectangle (with the red border) is defined by (row1, col1) = (2, 1) and (row2, co

AOJ DSL_2_D Range Update Query (RUQ)

Range Update Query 数列 A = {a0,a1 ,...,an−1} に対し.次の2つの操作を行うプログラムを作成せよ. update(s,t,x): as,as+1,...,at をxに変更する. find(i): ai の値を出力する. ただし.ai (i=0,1,...,n−1)は.231-1で初期化されているものとする. 入力 n q query1 query2 : queryq 1行目にAの要素数n, クエリの数qが与えられる.続くq行にi 番目のクエリ queryi

[LeetCode] Range Sum Query 2D - Immutable

Very similar to Range Sum Query - Immutable, but we now need to compute a 2d accunulated-sum. In fact, if you work in computer vision, you may know a name for such an array --- Integral Image. To solve this problem, Stefan has already posted a very e

LeetCode:Range Sum Query - Immutable - 数组指定区间内的元素和

1.题目名称 Range Sum Query(数组指定区间内的元素和) 2.题目地址 https://leetcode.com/problems/range-sum-query-immutable/ 3.题目内容 英文:Given an integer array nums, find the sum of the elements between indices i and j (i ≤ j), inclusive. 中文:给定一个数组nums,求出索引i和j之间元素的和,i一定是小于或等于j

Range Sum Query 2D - Mutable &amp; Immutable

Range Sum Query 2D - Mutable Given a 2D matrix matrix, find the sum of the elements inside the rectangle defined by its upper left corner (row1, col1) and lower right corner (row2, col2). The above rectangle (with the red border) is defined by (row1,