题目链接
可以看出是差分和前缀和(差分的话自己并不熟练),这题主要是对前面知识进行回顾了差分和前缀和的知识。
解题思路:
- 首先这个先利用差分来记录每个点的值,这里利用差分,然后类似于前缀和的形式来求出每个位置的值
- 然后我们利用前缀和(二维前缀和)
- 然后最终求出即可
这里需要注意的是:(注意形式)
二维前缀和:
a[i][j] = a[i][j] + a[i - 1][j] + a[i][j - 1] - a[i - 1][j - 1];
求出结果:
a[x2][y2] - a[x1 - 1][y2] - a[x2][y1 - 1] + a[x1 - 1][y1 - 1];
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
long long a[2010][2010];
int main(){
int n, m, k, q;
scanf("%d%d%d%d",&n,&m,&k,&q);
for (int i = 0; i < k; i ++){
int x1, y1, x2, y2;
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
a[x1][y1] += 1;
a[x2 + 1][y1] -= 1;
a[x1][y2 + 1] -= 1;
a[x2 + 1][y2 + 1] += 1;
}
// 差分完每一块的值
for (int i = 1; i <= n; i++){
for (int j = 1; j <= m; j ++){
a[i][j] = a[i][j] + a[i - 1][j] + a[i][j - 1] - a[i - 1][j - 1];
}
}
// 前缀和
for (int i = 1; i <= n; i++){
for (int j = 1; j <= m; j ++){
a[i][j] = a[i][j] + a[i - 1][j] + a[i][j - 1] - a[i - 1][j - 1];
}
}
for (int i = 0 ; i < q; i ++){
int x1, y1, x2, y2;
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
printf("%lld\n",a[x2][y2] - a[x1 - 1][y2] - a[x2][y1 - 1] + a[x1 - 1][y1 - 1]);
}
return 0;
}