Submission #415771

#TimeUsernameProblemLanguageResultExecution timeMemory
415771MlxaRectangles (IOI19_rect)C++14
27 / 100
5103 ms86712 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 / 2; i > 0; i /= 2) { for (int j = j0 / 2; j > 0; j /= 2) { t[i][j] = max(t[i][j], val); } } } int query(int li0, int ri0, int lj0, int rj0) { int ans = -INF; li0 += N, ri0 += N, lj0 += N, rj0 += N; 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]); } } } 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 = -getmax(l, li, lj, ri, rj); if (cl < lj - 1) { return; } int cu = -getmax(u, li, lj, ri, rj); if (cu < li - 1) { return; } int cr = getmax(r, li, lj, ri, rj); int cd = getmax(d, 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...