10.25T2 二维线段树
Description
为了准备校庆庆典,学校招募了一些学生组成了一个方阵,准备在庆典上演出。
这个方阵是一个n*m的矩形,第i行第j列有一名学生,他有一个能力值Ai,j。
校长会定期检查一个p*q的方阵,询问这个方阵的学生能力值之和,或是学生能力值的最大值,或是学生能力值的最小值。由于校长不喜欢一个方阵长宽之比差太多,他每次询问的方阵的长不会超过宽的两倍。作为校庆筹办组组长的你,应该迅速并准确的回答校长所问的问题。
这个方阵是一个n*m的矩形,第i行第j列有一名学生,他有一个能力值Ai,j。
校长会定期检查一个p*q的方阵,询问这个方阵的学生能力值之和,或是学生能力值的最大值,或是学生能力值的最小值。由于校长不喜欢一个方阵长宽之比差太多,他每次询问的方阵的长不会超过宽的两倍。作为校庆筹办组组长的你,应该迅速并准确的回答校长所问的问题。
Input
第一行包含两个整数n,m,表示这个方阵的两条边的长度。
接下来n行,每行m个数,表示每个学生的能力值。
接下来一行包含一个整数q,表示校长的询问数。
接下来q行,每行先一个字符串s,接下来4个整数x1,y1,x2,y2,保证x1≤x2,y1≤y2,设以第x1行y1列为左上角,第x2行y2列为右下角的方阵为P。(本题为0下标)
若字符串内容为“SUM”,请求出P中所有学生的能力值之和。
若字符串内容为“MAX”,请求出P中所有学生的能力值的最大值。
若字符串内容为“MIN”,请求出P中所有学生的能力值的最小值。
接下来n行,每行m个数,表示每个学生的能力值。
接下来一行包含一个整数q,表示校长的询问数。
接下来q行,每行先一个字符串s,接下来4个整数x1,y1,x2,y2,保证x1≤x2,y1≤y2,设以第x1行y1列为左上角,第x2行y2列为右下角的方阵为P。(本题为0下标)
若字符串内容为“SUM”,请求出P中所有学生的能力值之和。
若字符串内容为“MAX”,请求出P中所有学生的能力值的最大值。
若字符串内容为“MIN”,请求出P中所有学生的能力值的最小值。
Output
输出总共q行,第i行的数为第i组询问对应的答案ansi。
Sample Input
3 3
1 2 3
4 5 6
7 8 9
3
SUM 0 0 1 1
MAX 0 0 2 2
MIN 0 1 1 1
Sample Output
12
9
2
Hint
【样例解释】
对于第一组询问,能力值之和为1+2+4+5=12。
对于第二组询问,能力值最大的位置为第2行第2列。
对于第三组询问,能力值最小的位置为第0行第1列。
【数据规模和约定】
对于40%的数据,n,m≤200,q≤200
对于60%的数据,n,m≤300,q≤100000
对于80%的数据,n,m≤500,q≤500000
对于100%的数据,n,m≤800,q≤500000,0≤Aij≤3000,每个询问的方阵的长不超过宽的两倍。
对于第一组询问,能力值之和为1+2+4+5=12。
对于第二组询问,能力值最大的位置为第2行第2列。
对于第三组询问,能力值最小的位置为第0行第1列。
【数据规模和约定】
对于40%的数据,n,m≤200,q≤200
对于60%的数据,n,m≤300,q≤100000
对于80%的数据,n,m≤500,q≤500000
对于100%的数据,n,m≤800,q≤500000,0≤Aij≤3000,每个询问的方阵的长不超过宽的两倍。
二维线段树的板子。。。emmmm(好难写啊)
code:
1 #include<iostream> 2 #include<cstdio> 3 #include<string> 4 #define lc (p<<1) 5 #define rc (p<<1|1) 6 #define N 3301 7 #define max(i,j) i>j?i:j 8 #define min(i,j) i<j?i:j 9 using namespace std; 10 const int inf=0x3f3f3f3f; 11 int MAX=0,MIN=9999999; 12 int n,m; 13 int g[801][801],sum[801][801]; 14 struct segY { 15 struct node { 16 int l,r,min,max; 17 node() { 18 min=9999999; 19 } 20 } t[N]; 21 int up,down; 22 void pushup(int p) { 23 t[p].max=max(t[lc].max,t[rc].max); 24 t[p].min=min(t[lc].min,t[rc].min); 25 } 26 void build(int p,int l,int r) { 27 t[p].l=l,t[p].r=r; 28 if(l==r) { 29 for(int i=down; i<=up; i++)t[p].max=max(t[p].max,g[i][l]),t[p].min=min(t[p].min,g[i][l]); 30 return; 31 } 32 int mid=l+r>>1; 33 build(lc,l,mid); 34 build(rc,mid+1,r); 35 pushup(p); 36 } 37 int query_max(int p,int ql,int qr) { 38 if(ql<=t[p].l&&t[p].r<=qr) { 39 return t[p].max; 40 } 41 int a1=0,a2=0; 42 int mid=t[p].l+t[p].r>>1; 43 if(ql<=mid)a1=query_max(lc,ql,qr); 44 if(qr>mid)a2=query_max(rc,ql,qr); 45 return a1>a2?a1:a2; 46 } 47 int query_min(int p,int ql,int qr) { 48 if(ql<=t[p].l&&t[p].r<=qr) { 49 return t[p].min; 50 } 51 int a1=inf,a2=inf; 52 int mid=t[p].l+t[p].r>>1; 53 if(ql<=mid)a1=query_min(lc,ql,qr); 54 if(qr>mid)a2=query_min(rc,ql,qr); 55 return a1>a2?a2:a1; 56 } 57 }; 58 struct segX { 59 int l,r; 60 segY Y; 61 } t[800*4]; 62 void Build(int p,int l,int r) { 63 t[p].l=l,t[p].r=r; 64 t[p].Y.down=l,t[p].Y.up=r; 65 t[p].Y.build(1,1,m); 66 if(l==r)return; 67 int mid=l+r>>1; 68 Build(lc,l,mid); 69 Build(rc,mid+1,r); 70 } 71 int Query_min(int p,int x1,int y1,int x2,int y2) { 72 if(x1<=t[p].l&&t[p].r<=x2) { 73 return t[p].Y.query_min(1,y1,y2); 74 } 75 int a1=inf,a2=inf; 76 int mid=t[p].l+t[p].r>>1; 77 if(x1<=mid)a1=Query_min(lc,x1,y1,x2,y2); 78 if(x2>mid)a2=Query_min(rc,x1,y1,x2,y2); 79 return a1>a2?a2:a1; 80 } 81 int Query_max(int p,int x1,int y1,int x2,int y2) { 82 if(x1<=t[p].l&&t[p].r<=x2) { 83 return t[p].Y.query_max(1,y1,y2); 84 } 85 int a1=0,a2=0; 86 int mid=t[p].l+t[p].r>>1; 87 if(x1<=mid)a1=Query_max(lc,x1,y1,x2,y2); 88 if(x2>mid)a2=Query_max(rc,x1,y1,x2,y2); 89 return a1<a2?a2:a1; 90 } 91 long long read() { 92 long long x=0,f=1; 93 char c=getchar(); 94 while(!isdigit(c)) { 95 if(c=='-')f=-1; 96 c=getchar(); 97 } 98 while(isdigit(c)) { 99 x=(x<<3)+(x<<1)+c-'0'; 100 c=getchar(); 101 } 102 return x*f; 103 } 104 int main() { 105 n=read(),m=read(); 106 for(int i=1; i<=n; i++) { 107 for(int j=1; j<=m; j++) { 108 g[i][j]=read(); 109 sum[i][j]=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]+g[i][j]; 110 } 111 } 112 Build(1,1,n); 113 int Q; 114 Q=read(); 115 char opt[5]; 116 while(Q--) { 117 scanf("%s",opt); 118 if(opt[1]=='U') { 119 int x1,x2,y1,y2; 120 x1=read(),y1=read(),x2=read(),y2=read(); 121 x1++,x2++,y1++,y2++; 122 cout<<sum[x2][y2]-sum[x1-1][y2]-sum[x2][y1-1]+sum[x1-1][y1-1]<<'\n'; 123 } 124 if(opt[1]=='A') { 125 int x1,x2,y1,y2; 126 x1=read(),y1=read(),x2=read(),y2=read(); 127 x1++,x2++,y1++,y2++; 128 cout<<Query_max(1,x1,y1,x2,y2)<<'\n'; 129 } 130 if(opt[1]=='I') { 131 int x1,x2,y1,y2; 132 x1=read(),y1=read(),x2=read(),y2=read(); 133 x1++,x2++,y1++,y2++; 134 cout<<Query_min(1,x1,y1,x2,y2)<<'\n'; 135 } 136 } 137 return 0; 138 }
over