二维线段树题,求矩阵内的子矩阵中最小的值
View Code
1 #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
