题解
题目大意 给你一个n*m的矩形 有k个黑点 问这个矩形 不包含黑点的子矩形有多少个
f[i]表示当前枚举状态下 i列的最低黑点位置
暴力枚举子矩形下边界 右边界 利用f数组不断取min则为子矩形的上边界 从右向左扫描
子矩形个数等于枚举子矩形(确定上右左边界的情况下)个数为下边界-f[左边界]
AC代码
#include <stdio.h>
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const int MAXN = 1e5 + 10;
int g[MAXN][120], f[120];
int main()
{
#ifdef LOCAL
freopen("C:/input.txt", "r", stdin);
#endif
int T;
cin >> T;
for (int ti = 1; ti <= T; ti++)
{
memset(g, 0, sizeof(g));
memset(f, 0, sizeof(f));
int n, m, k;
cin >> n >> m >> k;
for (int i = 0; i < k; i++)
{
int x, y;
scanf("%d%d", &x, &y);
g[x][y] = 1;
}
ll ans = 0;
for (int i = 1; i <= n; i++) //矩形下边界
{
for (int j = 1; j <= m; j++) //只更新当前行 下面的黑点不会对当前行造成影响
if (g[i][j])
f[j] = i; //第i列最低的黑点位置
for (int r = 1; r <= m; r++) //矩形右边界
{
int mi = INF; //矩形上边界+1
for (int l = r; l >= 1; l--)
{
mi = min(mi, i - f[l]); //从右向左扫 子矩形个数为下边界-最低黑点+1
ans += mi;
}
}
}
printf("Case #%d: %lld\n", ti, ans);
}
return 0;
}