题解:P13647 [NOISG 2016] Fabric
题意
给定一个
题解
简单题,击杀了。
考虑枚举矩形下边界
思考
思考正解怎么做。不妨暴力枚举上边界
考虑预处理出
可以直接
这样节点
:::success[代码]
#include <bits/stdc++.h>
using namespace std;
#define lowbit(x) ((x) & -(x))
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pii;
const int N = 2e3 + 5;
template<typename T> inline void chk_min(T &x, T y) { x = min(x, y); }
template<typename T> inline void chk_max(T &x, T y) { x = max(x, y); }
int n, m, k, h[N], W[N];
int top, stk[N], ls[N], rs[N];
ll ans, suf[N], f[N][N];
bool a[N][N];
ll calc(ll x) { return x * (x + 1) >> 1; }
void prework() {
for (int w = 1; w <= m; ++w) for (int h = 1; h <= n; ++h) {
ll x = (k + h - 1) / h;
f[w][h] = f[w][h - 1] + (x <= w ? calc(w - x + 1) : 0);
}
}
int build() {
top = 0, fill(ls + 1, ls + m + 1, 0), fill(rs + 1, rs + m + 1, 0);
for (int i = 1; i <= m; ++i) {
while (top && h[stk[top]] >= h[i]) ls[i] = stk[top--];
rs[stk[top]] = i, stk[++top] = i;
}
return stk[1];
}
void dfs(int x, int fx) {
W[x] = 1;
if (ls[x]) dfs(ls[x], x), W[x] += W[ls[x]];
if (rs[x]) dfs(rs[x], x), W[x] += W[rs[x]];
ans += f[W[x]][h[x]] - f[W[x]][h[fx]];
}
int main() {
ios::sync_with_stdio(0), cin.tie(0);
cin >> n >> m >> k, prework();
for (int i = 1; i <= n; ++i) for (int j = 1; j <= m; ++j) cin >> a[i][j];
for (int d = 1; d <= n; ++d) {
for (int i = 1; i <= m; ++i) h[i] = !a[d][i] ? h[i] + 1 : 0;
dfs(build(), 0);
}
cout << ans;
return 0;
}
:::