제출 #415781

#제출 시각아이디문제언어결과실행 시간메모리
415781MlxaRectangles (IOI19_rect)C++14
49 / 100
5104 ms117952 KiB
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define all(x) x.begin(), x.end()
#define mp make_pair
#define mt make_tuple
#define x first
#define y second
#include "rect.h"

namespace my {

const int N = 1 << 10;
const int INF = 0x3f3f3f3f;

struct st2d {
	int t[2 * N][2 * N];
	void build(int a[N][N]) {
		fill_n(t[0], 4 * N * N, -INF);
		for (int i = 0; i < N; ++i) {
			for (int j = 0; j < N; ++j) {
				update(i, j, a[i][j]);
			}
		}
	}
	void update(int i0, int j0, int val) {
		i0 += N, j0 += N;
		for (int i = i0; i > 0; i /= 2) {
			for (int j = j0; j > 0; j /= 2) {
				t[i][j] = max(t[i][j], val);
			}
		}
	}
	int sub(int k, int l, int r) {
		int *arr = t[k];
		int ans = -INF;
		for (; l <= r; l /= 2, r /= 2) {
			if (l % 2 == 1) {
				ans = max(ans, arr[l++]);
			}
			if (r % 2 == 0) {
				ans = max(ans, arr[r--]);
			}
		}
		return ans;
	}
	int query(int li0, int lj0, int ri0, int rj0) {
		int ans = -INF;
		li0 += N, ri0 += N, lj0 += N, rj0 += N;
		for (int li = li0, ri = ri0; li <= ri; li /= 2, ri /= 2) {
			if (li % 2 == 1) {
				ans = max(ans, sub(li++, lj0, rj0));
			}
			if (ri % 2 == 0) {
				ans = max(ans, sub(ri--, lj0, rj0));
			}
		}
		
		// cout << "===" << endl;
		// for (int i = li0; i <= ri0; ++i) {
		// 	for (int j = lj0; j <= rj0; ++j) {
		// 		// cout << "# " << t[i][j] << endl;
		// 		ans = max(ans, t[i][j]);
		// 	}
		// }
		return ans;
		// for (int li = li0, ri = ri0; li <= ri; li = (li + 1) / 2, ri = (ri - 1) / 2) {
		// 	for (int lj = lj0, rj = rj0; lj <= rj; lj = (lj + 1) / 2, rj = (rj - 1) / 2) {
		// 		if (li % 2 == 1 && lj % 2 == 1) {
		// 			ans = max(ans, t[li][lj]);
		// 		}
		// 		if (ri % 2 == 0 && rj % 2 == 0) {
		// 			ans = max(ans, t[ri][rj]);
		// 		}
		// 		if (li % 2 == 1 && rj % 2 == 0) {
		// 			ans = max(ans, )
		// 		}
		// 	}
		// }
		return ans;
	}
} tl, tr, tu, td;

int getmax(int a[N][N], int li, int lj, int ri, int rj) {
	int ans = -(int)1e9;;
	for (int i = li; i <= ri; ++i) {
		for (int j = lj; j <= rj; ++j) {
			ans = max(ans, a[i][j]);
		}
	}
	return ans;
}

int n, m;
int a[N][N];
int l[N][N], r[N][N], u[N][N], d[N][N];
set<tuple<int, int, int, int>> mem;

void dfs(int li, int lj, int ri, int rj) {
	while (1) {
		if (ri > n - 2 || rj > m - 2) {
			return;
		}
		int cl = -tl.query(li, lj, ri, rj);
		if (cl < lj - 1) {
			return;
		}
		int cu = -tu.query(li, lj, ri, rj);
		if (cu < li - 1) {
			return;
		}
		int cr = tr.query(li, lj, ri, rj);
		int cd = td.query(li, lj, ri, rj);
		if (cr <= rj + 1 && cd <= ri + 1) {
			break;
		}
		rj = max(rj, cr - 1);
		ri = max(ri, cd - 1);
	}
	if (!mem.emplace(li, lj, ri, rj).y) {
		return;
	}
	// cout << "add " << li << " " << lj << " " << ri << " " << rj << endl;
	dfs(li, lj, ri + 1, rj);
	dfs(li, lj, ri, rj + 1);
}
}

ll count_rectangles(vector<vector<int>> _a) {
	using namespace my;
	n = (int)_a.size(), m = (int)_a[0].size();
	for (int i = 0; i < n; ++i) {
		for (int j = 0; j < m; ++j) {
			a[i][j] = _a[i][j];
		}
	}
	for (int i = 0; i < n; ++i) {
		for (int j = 0; j < m; ++j) {
			l[i][j] = j - 1;
			while (l[i][j] >= 0 && a[i][l[i][j]] <= a[i][j]) {
				l[i][j] = l[i][l[i][j]];
			}
			u[i][j] = i - 1;
			while (u[i][j] >= 0 && a[u[i][j]][j] <= a[i][j]) {
				u[i][j] = u[u[i][j]][j];
			}
		}
	}
	for (int i = n - 1; i >= 0; --i) {
		for (int j = m - 1; j >= 0; --j) {
			r[i][j] = j + 1;
			while (r[i][j] < m && a[i][r[i][j]] <= a[i][j]) {
				r[i][j] = r[i][r[i][j]];
			}
			d[i][j] = i + 1;
			while (d[i][j] < n && a[d[i][j]][j] <= a[i][j]) {
				d[i][j] = d[d[i][j]][j];
			}
		}
	}
	for (int i = 0; i < n; ++i) {
		for (int j = 0; j < m; ++j) {
			l[i][j] *= -1;
			u[i][j] *= -1;
		}
	}
	tl.build(l);
	tr.build(r);
	tu.build(u);
	td.build(d);
	// for (int i = 0; i < n; ++i) {
	// 	for (int j = 0; j < m; ++j) {
	// 		cout << l[i][j] << " ";
	// 	}
	// 	cout << endl;
	// }
	for (int i = 1; i < n - 1; ++i) {
		for (int j = 1; j < m - 1; ++j) {
			dfs(i, j, i, j);
		}
	}
	return (int)mem.size();
}

#ifdef LC
#include "grader.cpp"
#endif
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...