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;
}
posted @ 2020-12-03 22:17  wansheking  阅读(127)  评论(0)    收藏  举报