博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

zoj 2859 RMQ问题,Sparse Table解法

Posted on 2011-03-08 20:48  天地玄黄  阅读(459)  评论(0编辑  收藏  举报

预处理时间复杂度为 O(NlogN),查找时间复杂度为 O(1)

/*The RMQ question, using Sparse Table(ST) algorithm to solve it
 *http://www.topcoder.com/tc?module=Static&d1=tutorials&d2=lowestCommonAncestor
 *
 *initRMQ: M[N][logN][N][logN], i,j,u,v
 *		j: from 0 to logN (2^j <= N)
 *		 v: from 0 to logN (2^v <= N)
 *		  i: from 0 to N-1 (i+2^j-1 < N)
 *		   u: from o to N-1 (u+2^v-1 < N)
 *			M[i][j][u][v] = 1) matrix[i][u], if j==0&&v==0;
 *							2) min(M[i][j-1][u][v], M[i+(2^(j-1))][j-1][u][v]), if v==0
 *							3) min(M[i][j][u][v-1], M[i][j][u+(2^(v-1))][v-1]), else
 */
#include <stdio.h>

#define min(a,b) (((a)<(b))?(a):(b))
#define N 310

int matrix[N][N];
int M[N][9][N][9];

int log_2(int n)
{
	int pos = -1,
		i = 1;
	while(i <= n)
	{
		if( (i&(i-1)) == 0)
			pos += 1;
		i++;
	}
	return pos;
}

void initRMQ(int n)
{
	int i, j, u, v;
	int logn = log_2(n);

	for(j = 0; j <= logn; j++)
		for(v = 0; v <= logn; v++)
			for(i = 0; i+(1<<j)-1 < n; i++) /*i+(1<<j)-1 < n*/
				for(u = 0; u+(1<<v)-1 < n; u++) /*u+(1<<v)-1 < n*/
				{
					if(j == 0 && v == 0)
					{
						M[i][j][u][v] = matrix[i][u];
					}
					else if(v == 0)
					{
						M[i][j][u][v] = min(M[i][j-1][u][v], M[i+(1<<(j-1))][j-1][u][v]);
					}
					else
					{
						M[i][j][u][v] = min(M[i][j][u][v-1], M[i][j][u+(1<<(v-1))][v-1]);
					}
				}
}

int askRMQ(int i, int j, int u, int v)
{
	int k = log_2(u-i+1);
	int t = log_2(v-j+1);

	int a = min(M[i][k][j][t], M[i][k][v-(1<<t)+1][t]);
	int b = min(M[u-(1<<k)+1][k][j][t], M[u-(1<<k)+1][k][v-(1<<t)+1][t]);
	
	return min(a,b);
}

int main()
{
	int t;
	scanf("%d", &t);
	while(t--)
	{
		int n;
		scanf("%d", &n);
		
		int i, j;
		for(i = 0; i < n; i++)
			for(j = 0; j < n; j++)
				scanf("%d", &(matrix[i][j]));

		initRMQ(n);

		int queries;
		scanf("%d", &queries);
		
		while(queries--)
		{
			int r1, c1, r2, c2;
			scanf("%d%d%d%d", &r1, &c1, &r2, &c2);
			printf("%d\n", askRMQ(r1-1, c1-1, r2-1, c2-1));
		}
	}

	return 0;
}

参考算法:http://www.topcoder.com/tc?module=Static&d1=tutorials&d2=lowestCommonAncestor