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
比较难理解的地方就是在push_up的时候。。其实对于某一个x维的节点对应着n 个节点。 那么我们要push_up(i)
的时候就要先把lson 和 rson 所有的x维对应的y叶节点找出最小的。 然后向上递归。
#include<bits/stdc++.h>
#define lson (i<<1)
#define rson (i<<1|1)
using namespace std;
const int N =305;
struct TreeY
{
int ly,ry;
int num;
};
int n;
int mp[N][N];
struct TreeX
{
int lx,rx;
TreeY trey[N<<2];
void push_upy(int i)
{
trey[i].num=min(trey[lson].num,trey[rson].num);
}
void buildy(int i,int lx,int rx,int l,int r)
{
trey[i].ly=l; trey[i].ry=r;
if(l==r){
if(lx==rx) trey[i].num=mp[lx][l];
return ;
}
int mid=(l+r)>>1;
buildy(lson,lx,rx,l,mid);
buildy(rson,lx,rx,mid+1,r);
push_upy(i);
}
int queryy(int i,int l,int r)
{
//cout<<"i "<<i<<" l "<<trey[i].ly<<" r "<<trey[i].ry <<endl;
//cout<<l<<" "<<r<<endl;
if(trey[i].ly==l&&trey[i].ry==r){
return trey[i].num;
}
int mid=(trey[i].ly+trey[i].ry)>>1;
if(r<=mid) return queryy(lson,l,r);
else if(l>mid) return queryy(rson,l,r);
else return min(queryy(lson,l,mid),queryy(rson,mid+1,r));
push_upy(i);
}
};
TreeX trx[N<<2];
void push_upx(int i,int ly,int ry,int si)
{
if(ly==ry){
trx[i].trey[si].num=min(trx[lson].trey[si].num,trx[rson].trey[si].num);
return ;
}
int mid=(ly+ry)>>1;
push_upx(i, ly,mid,si<<1); // !!!
push_upx(i, mid+1,ry,si<<1|1);
trx[i].trey[si].num=min(trx[lson].trey[si].num,trx[rson].trey[si].num);
}
void buildx(int i,int l,int r)
{
trx[i].lx=l; trx[i].rx=r;
if(l==r){
trx[i].buildy(1,l,r,1,n);
return ;
}
int mid=(l+r)>>1;
buildx(lson,l,mid);
buildx(rson,mid+1,r);
trx[i].buildy(1,l,r,1,n);
push_upx(i,1,n,1);
return ;
}
int queryx(int i,int lx,int rx,int ly,int ry)
{
//printf("i: %d lx %d rx %d ly %d ry %d\n",i,lx,rx,ly,ry);
if(trx[i].lx==lx&&trx[i].rx==rx){
return trx[i].queryy(1,ly,ry);
}
int mid=(trx[i].lx+trx[i].rx)>>1;
if(rx<=mid) return queryx(lson,lx,rx,ly,ry);
else if(lx>mid) return queryx(rson,lx,rx,ly,ry);
else{
return min(queryx(lson,lx,mid,ly,ry),queryx(rson,mid+1,rx,ly,ry));
}
}
int main()
{
int T;
scanf("%d",&T);
while(T--){
scanf("%d",&n);
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
scanf("%d",&mp[i][j]);
}
}
buildx(1,1,n);
int q;
scanf("%d",&q);
int rx,lx,ry,ly;
while(q--)
{
scanf("%d %d %d %d",&lx,&ly,&rx,&ry);
int ans=queryx(1,lx,rx,ly,ry);
printf("%d\n",ans);
}
}
return 0;
}