二维线段树题,求矩阵内的子矩阵中最小的值
View Code1 #include <cstdio> 2 #include <algorithm> 3 using namespace std; 4 #define lson l,m,rt<<1 5 #define rson m+1,r,rt<<1|1 6 #define maxn 301 7 int a[maxn][maxn]; 8 int setree[maxn<<2][maxn<<2]; 9 int n; 10 void build1(int num1,int num2,int l,int r,int rt) 11 { 12 if(l==r){ 13 setree[rt][num1]=a[l][num2]; 14 return; 15 } 16 int m=(l+r)>>1; 17 build1(num1,num2,lson); 18 build1(num1,num2,rson); 19 setree[rt][num1]=min(setree[rt<<1][num1],setree[rt<<1|1][num1]); 20 } 21 void build2(int num,int l,int r,int rt) 22 { 23 setree[rt][num]=min(setree[rt][num<<1],setree[rt][num<<1|1]); 24 if(l==r) 25 return; 26 int m=(l+r)>>1; 27 build2(num,lson); 28 build2(num,rson); 29 } 30 void build(int l,int r,int rt) 31 { 32 if(l==r){ 33 build1(rt,l,1,n,1); 34 return; 35 } 36 int m=(l+r)>>1; 37 build(lson); 38 build(rson); 39 build2(rt,1,n,1); 40 } 41 int subquery(int num,int l,int r,int rt,int L,int R) 42 { 43 if(L<=l&&r<=R) 44 return setree[rt][num]; 45 int m=(l+r)>>1; 46 int ans=1<<31-1; 47 if(L<=m) 48 ans=min(ans,subquery(num,lson,L,R)); 49 if(R>m) 50 ans=min(ans,subquery(num,rson,L,R)); 51 return ans; 52 } 53 int query(int l,int r,int rt,int L,int R,int l1,int r1) 54 { 55 if(L<=l&&r<=R) 56 return subquery(rt,1,n,1,l1,r1); 57 int m=(l+r)>>1; 58 int ans=1<<31-1; 59 if(L<=m) 60 ans=min(ans,query(lson,L,R,l1,r1)); 61 if(R>m) 62 ans=min(ans,query(rson,L,R,l1,r1)); 63 return ans; 64 } 65 int main() 66 { 67 int t; 68 scanf("%d",&t); 69 while(t--){ 70 scanf("%d",&n); 71 for(int i=1;i<=n;i++) 72 for(int j=1;j<=n;j++) 73 scanf("%d",&a[i][j]); 74 build(1,n,1); 75 int m; 76 scanf("%d",&m); 77 while(m--){ 78 int a,b,c,d; 79 scanf("%d%d%d%d",&a,&b,&c,&d); 80 printf("%d\n",query(1,n,1,b,d,a,c)); 81 } 82 } 83 return 0; 84 }
来源:https://www.cnblogs.com/kim888168/archive/2013/01/21/2870285.html