Matrix Searching 二维线段树

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/weixin_43880084/article/details/102671604

LINK
Matrix Searching
Time Limit: 10000 msMemory 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

扫描二维码关注公众号,回复: 7639769 查看本文章

-1
2

  • 怀疑上次写了个假算法,这依旧是二维线段树裸题
#include<bits/stdc++.h>
using namespace std;
const int inf=0x3f3f3f3f;
const int N=310;int n;
struct tr{
	int t[N<<2];
	void build(int l,int r,int rt)
	{
		t[rt]=inf;
		if(l==r) return ;
		int mid=(l+r)>>1;
		build(l,mid,rt<<1);
		build(mid+1,r,rt<<1|1);
	}
	void update(int y,int v,int l,int r,int rt)
	{
		if(l==r)
		{
			t[rt]=v;return ;
		}
		int mid=(l+r)>>1;
		if(mid>=y) update(y,v,l,mid,rt<<1);
		else update(y,v,mid+1,r,rt<<1|1);
		t[rt]=min(t[rt<<1],t[rt<<1|1]);
	}
	int query(int y1,int y2,int l,int r,int rt)
	{
		if(y1<=l&&r<=y2) return t[rt];
		int mid=(l+r)>>1;int s=inf;
		if(y1<=mid) s=query(y1,y2,l,mid,rt<<1);
		if(y2>mid) s=min(s,query(y1,y2,mid+1,r,rt<<1|1));
		return s; 
	}
}T[N<<2];
void build(int l,int r,int rt)
{
	T[rt].build(1,n,1);
	if(l==r) return ;
	int mid=(l+r)>>1;
	build(l,mid,rt<<1);
	build(mid+1,r,rt<<1|1);
}
void up(int ox,int oy,int l,int r,int yy)
{
	T[ox].t[oy]=min(T[ox<<1].t[oy],T[ox<<1|1].t[oy]);
	if(l==r) return ;
	int mid=(l+r)>>1;
	if(yy<=mid) up(ox,oy<<1,l,mid,yy);
	else up(ox,oy<<1|1,mid+1,r,yy);
}
void update(int x,int y,int v,int l,int r,int rt)
{
	if(l==r)
	{
		T[rt].update(y,v,1,n,1);return ;
	}
	int mid=(l+r)>>1;
	if(mid>=x) update(x,y,v,l,mid,rt<<1);
	else update(x,y,v,mid+1,r,rt<<1|1); 
	up(rt,1,1,n,y);
}
int query(int x1,int x2,int y1,int y2,int l,int r,int rt)
{
	if(l>=x1&&r<=x2)
	{
		return T[rt].query(y1,y2,1,n,1);
	}int mid=(l+r)>>1;int s=inf;
	if(mid>=x1) s= query(x1,x2,y1,y2,l,mid,rt<<1);
	if(mid<x2)  s=min(s,query(x1,x2,y1,y2,mid+1,r,rt<<1|1));
	return s;
}
int main()
{
	int tt;scanf("%d",&tt);
	while(tt--)
	{
		int aa;scanf("%d",&n);build(1,n,1);
		for(int i=1;i<=n;i++)
		{
			for(int j=1;j<=n;j++)
			{
				scanf("%d",&aa);
				update(i,j,aa,1,n,1);
			}
		}
		int m;scanf("%d",&m);
		while(m--)
		{
			int x1,x2,y1,y2;
			scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
			printf("%d\n",query(x1,x2,y1,y2,1,n,1));
		}
	}
} 
#include<bits/stdc++.h>
using namespace std;
const int N=301,inf=0x3f3f3f3f;
int t[N<<2][N<<2],a[N][N],m,n;
void up(int rt,int fa)
{
	t[fa][rt]=min(t[fa][rt<<1|1],t[fa][rt<<1]);
}
void buildy(int fa,int rt,int l,int r,int pos,int bz)
{
	if(l==r)
	{
		if(bz) t[fa][rt]=a[pos][l];
		else 
		{
			t[fa][rt]=min(t[fa<<1|1][rt],t[fa<<1][rt]);
		}return ;
	}
	int mid=(l+r)>>1;
	buildy(fa,rt<<1,l,mid,pos,bz);
	buildy(fa,rt<<1|1,mid+1,r,pos,bz);
	up(rt,fa); 
}
void build(int rt,int l,int r)
{
	if(l==r)
	{
		buildy(rt,1,1,n,l,1);
		return ;
	}
	int mid=(l+r)>>1;
	build(rt<<1,l,mid);
	build(rt<<1|1,mid+1,r);
	buildy(rt,1,1,n,l,0);
}
int queryy(int fa,int rt,int l,int r,int L,int R)
{
	if(L<=l&&R>=r)
	{
		return t[fa][rt];
	}
	int mid=(l+r)>>1; int s=inf;
	if(mid>=L) s=queryy(fa,rt<<1,l,mid,L,R);
	if(mid<R) s=min(s,queryy(fa,rt<<1|1,mid+1,r,L,R));
	return s;
}
int  query(int rt,int L,int R,int aa,int bb,int l,int r)
{
	if(L<=l&&R>=r)
	{
		return queryy(rt,1,1,n,aa,bb);
	}
	int mid=(l+r)>>1; int s=inf;
	if(mid>=L) s=query(rt<<1,L,R,aa,bb,l,mid);
	if(mid<R) s=min(s,query(rt<<1|1,L,R,aa,bb,mid+1,r));
	return s;
}
int main()
{
	int tt;scanf("%d",&tt);
	while(tt--)
	{
		scanf("%d",&n);
		for(int i=1;i<=n;i++)
		{
			for(int j=1;j<=n;j++)
			{
				scanf("%d",&a[i][j]);
			}
		}
		build(1,1,n);scanf("%d",&m);
		while(m--)
		{
			int x1,y1,x2,y2;
			scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
			printf("%d\n",query(1,x1,x2,y1,y2,1,n));
		}
	}
}

猜你喜欢

转载自blog.csdn.net/weixin_43880084/article/details/102671604