Largest Common Submatrix (单调栈)
https://nanti.jisuanke.com/t/42391
由于矩阵中每个数字不相同,可以将a,b两矩阵的相同数字的位置做减法,对于相减后的坐标矩阵,只考虑相同坐标的最大子矩阵即可
int n, m, cnt, a[maxn][maxn], b[maxn][maxn], px[maxm], py[maxm], dp[maxm], c[maxm];
int f[maxn][maxn], r[maxn], l[maxn];
pii pos[maxn], mat[maxn][maxn];
pii operator - (const pii& a, const pii& b) {
return make_pair(a.first - b.first, a.second - b.second);
}
void solve3() {
n = read(); m = read();
for (int i = 1; i <= n; ++i) for (int j = 1; j <= m; ++j) a[i][j] = read();
for (int i = 1; i <= n; ++i) for (int j = 1; j <= m; ++j) b[i][j] = read(), pos[b[i][j]] = make_pair(i, j);
for (int i = 1; i <= n; ++i) for (int j = 1; j <= m; ++j) mat[i][j] = make_pair(i, j) - pos[a[i][j]];
for (int i = 1; i <= n; ++i) for (int j = m; j >= 1; --j) {
f[i][j] = 1; if (j == m) continue;
if (mat[i][j] == mat[i][j + 1]) f[i][j] += f[i][j + 1];
}
int res = 0;
for (int j = 1; j <= m; ++j) {
stack<int> stk;
memset(l, 0, sizeof l); memset(r, 0, sizeof r);
for (int i = 1; i <= n; ++i) {
if (!stk.empty()) {
if (mat[i][j] != mat[i - 1][j]) {
while (!stk.empty()) {
r[stk.top()] = i - 1;
stk.pop();
}
}
}
while (!stk.empty() and f[i][j] < f[stk.top()][j]) {
l[i] = l[stk.top()];
r[stk.top()] = i - 1;
stk.pop();
}
if (!l[i]) l[i] = i;
stk.push(i);
}
while (!stk.empty()) {
r[stk.top()] = n;
stk.pop();
}
for (int i = 1; i <= n; ++i) res = max(res, f[i][j] * (r[i] - l[i] + 1));
}
printf("%d\n", res);
}
signed main() {
//ll n, m;
//test();
//init();
ll t = 1;
//t = rd();
while (t--) solve3();
//while (~scanf("%lld %lld", &m, &n)) solve(m, n);
return 0;
}