從這位強者的網誌轉錄:
http://gozule.blogspot.com/2009/02/range-minimummaximum-query-rmq.html
Input:array A[0, N]
Output: the index of minimum(maximum) value between two given indices.
RMQ的功能是若有一群資料放在array中,在經過preprocessing後,可在O(1)的時間內找出index i~j之間的最小(大)的元素。目前preprocessing最快是O(n),也就是只需要O(n)的時間就可以處理完成。
以下介紹O(nlog(n))的preprocessing方法,O(n)的方法是由此法去改進,所以先了解此法相當重要且因程式碼容易撰寫,所以也相當適合在ACM中使用。
假設array的長度2的n次方。
建立一個大小為n x log(n)的矩陣M,用來存放RMQ的結果,其中M[i][j]是指以index i開頭,長度為2^j次方內最小元素的index。
使用dynamic programming方法建立M,需O(nlogn) time。
//time complexity: O(nlogn)
void preprocess(int M[MAXN][LOGMAXN], int A[MAXN], int N)
{
int i, j;
//initialize M for the intervals with length 1
for (i = 0; i < N; i++)
M[i][0] = i;
//compute values from smaller to bigger intervals
for (j = 1; 1 << j <= N; j++)
for (i = 0; i + (1 << j) - 1 < N; i++)
if (A[M[i][j - 1]] < A[M[i + (1 << (j - 1))][j - 1]])
M[i][j] = M[i][j - 1];
else
M[i][j] = M[i + (1 << (j - 1))][j - 1];
}
//output: the index of the minimum value between index i and j
int RMQ(int i, int j, int M[MAXN][LOGMAXN], int A[MAXN], int N)
{
if(i<0 || i>=N || j<0 || j>=N)
return -1;
if(i > j) //swap i, j
i ^= j, j ^= i, i ^= j;
int k = (int)(log(j-i)/log(2.0)),
rem = j-(1<
}
2009年3月29日 星期日
Range Minimum(Maximum) Query, RMQ
2009年3月28日 星期六
宜蘭縣三星鄉的漿腥淫
訂閱:
文章 (Atom)