ZOJ 1859 Matrix Searching(二维线段树)

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1859

Matrix Searching

Time Limit: 10 Seconds       Memory Limit: 32768 KB

Given an n*n matrix A, whose entries Ai,j are integer numbers ( 1 <= i <= n, 1 <= j <= n ). An operation FIND the minimun number in a given ssub-matrix.

Input

The first line of the input contains a single integer T , the number of test cases.

For each test case, the first line contains one integer n (1 <= n <= 300), which is the sizes of the matrix, respectively. The next n lines with n integers each gives the elements of the matrix.

The next line contains a single integer N (1 <= N <= 1,000,000), the number of queries. The next N lines give one query on each line, with four integers r1, c1, r2, c2 (1 <= r1 <= r2 <= n, 1 <= c1 <= c2 <= n), which are the indices of the upper-left corner and lower-right corner of the sub-matrix in question.

Output

For each test case, print N lines with one number on each line, the required minimum integer in the sub-matrix.

Sample Input

1
2
2 -1
2 3
2
1 1 2 2
1 1 2 1

Sample Output

-1
2


Author:  PENG, Peng
Source:  ZOJ Monthly, June 2007



题意:
给出一个n*n的矩阵,有m次询问,求每次询问子矩阵中的最小值。
分析:
显然二维线段树随便乱搞搞即可了, 线段树维护区域内的最小值。注意二维上的"pushup()"的写法,实际上也是要维护一棵线段树。

/*
 *
 *	Author	:	fcbruce
 *
 *	Date	:	2014-08-24 13:03:05 
 *
 */
#include <cstdio>
#include <iostream>
#include <sstream>
#include <cstdlib>
#include <algorithm>
#include <ctime>
#include <cctype>
#include <cmath>
#include <string>
#include <cstring>
#include <stack>
#include <queue>
#include <list>
#include <vector>
#include <map>
#include <set>
#define sqr(x) ((x)*(x))
#define LL long long
#define itn int
#define INF 0x3f3f3f3f
#define PI 3.1415926535897932384626
#define eps 1e-10

#ifdef _WIN32
	#define lld "%I64d"
#else
	#define lld "%lld"
#endif

#define maxm 
#define maxn 300

using namespace std;

int n;
int minv[maxn<<2][maxn<<2];

inline void pushup(int k_2d,int k)
{
	minv[k_2d][k]=min(minv[k_2d][k*2+1],minv[k_2d][k*2+2]);
}

void build_1d(int k,int l,int r,int k_2d,int type)
{
	if (r-l==1)
	{
		if (type)
			scanf( "%d",&minv[k_2d][k]);
		else
			minv[k_2d][k]=min(minv[k_2d*2+1][k],minv[k_2d*2+2][k]);
			
		return ;
	}
	
	build_1d(k*2+1,l,l+r>>1,k_2d,type);
	build_1d(k*2+2,l+r>>1,r,k_2d,type);
	
	pushup(k_2d,k);
}

void build_2d(int k,int l,int r)
{
	if (r-l==1)
		build_1d(0,0,n,k,1);
	else
	{
		build_2d(k*2+1,l,l+r>>1);
		build_2d(k*2+2,l+r>>1,r);
		
		build_1d(0,0,n,k,0);
	}
}

int query_1d(int a,int b,int k,int l,int r,int k_2d)
{
	if (b<=l || r<=a)	return INF;
	if (a<=l && r<=b)	return minv[k_2d][k];
	
	return min(query_1d(a,b,k*2+1,l,l+r>>1,k_2d),query_1d(a,b,k*2+2,l+r>>1,r,k_2d));
 
}

int query_2d(int a,int b,int ya,int yb,int k,int l,int r)
{
	if (b<=l || r<=a)	return INF;
	if (a<=l && r<=b)	return query_1d(ya,yb,0,0,n,k);
	
	return min(query_2d(a,b,ya,yb,k*2+1,l,l+r>>1),query_2d(a,b,ya,yb,k*2+2,l+r>>1,r));
}

int main()
{
	#ifndef ONLINE_JUDGE
		freopen("/home/fcbruce/文档/code/t","r",stdin);
	#endif // ONLINE_JUDGE
	
	int T_T;
	scanf( "%d",&T_T);
	
	while (T_T--)
	{
		scanf( "%d",&n);
		build_2d(0,0,n);
		
		int m;
		scanf( "%d",&m);
		int x1,x2,y1,y2;
		while (m--)
		{
			scanf( "%d%d%d%d",&x1,&y1,&x2,&y2);
			x1--;
			y1--;
			printf( "%d\n",query_2d(x1,x2,y1,y2,0,0,n));
		}
	}
	
	
	return 0;
}



你可能感兴趣的:(search)