牛客寒假算法基础集训营6 E 海啸
链接:https://ac.nowcoder.com/acm/contest/332/E
来源:牛客网
有一个沿海地区,可以看作有n行m列的城市,第i行第j列的城市海拔为h[i][j]。
由于沿海,所以这个地区经常会发生海啸。
海啸发生时,部分城市会被淹没,具体来说,海水高度会达到d,因此海拔低于d的城市都会被淹没。
现在有q次询问,每次问你一个矩形区域中,有多少城市不会被淹没。
由于沿海,所以这个地区经常会发生海啸。
海啸发生时,部分城市会被淹没,具体来说,海水高度会达到d,因此海拔低于d的城市都会被淹没。
现在有q次询问,每次问你一个矩形区域中,有多少城市不会被淹没。
输入描述:
第一行三个整数n,m,d,具体含义见题目描述。
接下来n行,每行m个整数,其中第i行第j列的整数为h[i][j],具体含义见题目描述。
第n+2行一个整数q,表示询问数。
接下来q行,每行四个整数a,b,x,y,
表示询问从第a行第b列到第x行第y列的矩形地区中,有多少地区不会被淹没。
即有多少个i,j,满足 a≤i≤x,b≤j≤ya≤i≤x,b≤j≤y ,且 h[i][j]≥dh[i][j]≥d 。
输出描述:
共q行,第i行一个整数,表示第i个询问的答案。
示例1
输出
复制2 3
记得之前见过类似的 以为是 二维线段树
看了题解 是前缀和。。
首先 明白如何求 (a,b) (x,y) 矩阵的和
容斥定理
可以看出 求 (a,b)~(x,y)的和 = sum(x,y)-sum(x,b-1)-sum(a-1,y)+sum(a-1,b-1)
其中 sum(s,t) 为 (1,1)~(s,t)的和
也即 结果 = 总矩阵 - 绿矩阵 - 黄矩阵 + 红色区域
那么如何利用 前缀和 求 sum呢
具体见代码 ,结合二维数阵 理解
1 #include<stdio.h> 2 const int maxn=2000010;//2倍大小 3 int n,m,d; 4 int h[maxn],sum[maxn]; 5 6 int main() { 7 scanf("%d%d%d",&n,&m,&d); 8 int t; 9 for(int i=1;i<=n;i++) 10 for(int j=1;j<=m;j++) { 11 scanf("%d",&t); 12 h[i*(m+1)+j]=t>=d?1:0; 13 sum[i*(m+1)+j]=sum[i*(m+1)+j-1]+sum[(i-1)*(m+1)+j]-sum[(i-1)*(m+1)+j-1]+h[i*(m+1)+j]; 14 } 15 int ans,q,a,b,x,y; 16 scanf("%d",&q); 17 while(q--) { 18 ans=0; 19 scanf("%d%d%d%d",&a,&b,&x,&y); 20 ans=sum[x*(m+1)+y]-sum[(a-1)*(m+1)+y]-sum[x*(m+1)+b-1]+sum[(a-1)*(m+1)+b-1]; 21 printf("%d\n",ans); 22 } 23 return 0; 24 }
埋骨何须桑梓地,人生无处不青山