题意:n*m的一个矩形,其中有k个位置为空,问你该矩形内有多少小矩形?
$ 1<=n,k<=1e5, 1<=m <= 100$
分析:详解:不怎么容易理解!
无空位置时:从上到下先枚举行i,从左到右再枚举列j,对于(i,j),那么右端紧靠着j列的矩形高度为1,2,3…i 的各有1个,所以ans += i;
有空位置时:从上到下先枚举行i,从左到右再枚举列j,对于(i,j),那么右端紧靠着j列的矩形高度为1,2,3…i - a[k] 的各有1个(k从j列向左遍历),所以ans += min(i - a[k]);
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef unsigned long long ull;
typedef pair<LL, LL>pii;
const int MAXN = 1e5 + 10;
const LL MOD = 1e9 +7;
bool vis[MAXN][105];
int a[MAXN];
int main() {
int T, n, m, q;
scanf("%d", &T);
for(int cs = 1; cs <= T; ++cs) {
memset(vis, 0, sizeof(vis));
memset(a, 0, sizeof(a));
scanf("%d %d %d", &n, &m, &q);
while(q--) {
int x, y;
scanf("%d %d", &x, &y);
vis[x][y] = 1;
}
LL ans = 0;
for(int i = 1; i <= n; ++i) {
for(int j = 1; j <= m; ++j) {
if(vis[i][j]) a[j] = i;
}
for(int j = 1; j <= m; ++j) {
LL cnt = (1ll << 62);
for(int k = j; k >= 1; --k) {
cnt = min(cnt, (i - a[k]) * 1ll);
ans += cnt;
}
}
}
printf("Case #%d: %lld\n", cs, ans);
}
return 0;
}