Submission #223437

#TimeUsernameProblemLanguageResultExecution timeMemory
223437MrDominoRectangles (IOI19_rect)C++14
72 / 100
5095 ms380080 KiB
#include <bits/stdc++.h> #include "rect.h" using namespace std; const int N = 2500 + 7; int n; int m; int a[N][N]; int st[N][N]; int dr[N][N]; int sus[N][N]; int jos[N][N]; int stv[N]; int top; struct KEKMAN { int x; int l; int r; }; bool operator < (KEKMAN a, KEKMAN b) { if (a.x != b.x) { return a.x < b.x; } else { return a.r < b.r; } } bool operator == (KEKMAN a, KEKMAN b) { return (a.x == b.x && a.r == b.r); } vector<KEKMAN> rows; vector<KEKMAN> cols; bool good(int r, int c) { return (1 < r && 1 < c && r < n && c < m); } struct T { int a; int b; int c; int d; }; bool operator < (T f, T s) { if (f.a != s.a) return f.a < s.a; if (f.b != s.b) return f.b < s.b; if (f.c != s.c) return f.c < s.c; return f.d < s.d; } bool operator != (T f, T s) { if (f.a != s.a) return 1; if (f.b != s.b) return 1; if (f.c != s.c) return 1; if (f.d != s.d) return 1; return 0; } vector<T> solutions; void check(int r1, int c1, int r2, int c2) { if (!good(r1, c1) || !good(r2, c2)) { return; } if (r1 > r2 || c1 > c2) { return; } for (int r = r1; r <= r2; r++) { if (dr[r][c1] != c2 && st[r][c2] != c1) { return; } } for (int c = c1; c <= c2; c++) { if (jos[r1][c] != r2 && sus[r2][c] != r1) { return; } } solutions.push_back({r1, c1, r2, c2}); } int lx[N][N]; int rx[N][N]; int ly[N][N]; int ry[N][N]; long long count_rectangles(vector<vector<int>> b) { n = (int) b.size(); m = (int) b[0].size(); for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { a[i][j] = b[i - 1][j - 1]; } } for (int i = 1; i <= n; i++) { top = 0; stv[0] = 0; for (int j = 1; j <= m; j++) { while (top && a[i][stv[top]] < a[i][j]) { top--; } st[i][j - 1] = stv[top] + 1; stv[++top] = j; } top = 0; stv[0] = m + 1; for (int j = m; j >= 1; j--) { while (top && a[i][stv[top]] < a[i][j]) { top--; } dr[i][j + 1] = stv[top] - 1; stv[++top] = j; } } for (int j = 1; j <= m; j++) { top = 0; stv[0] = 0; for (int i = 1; i <= n; i++) { while (top && a[stv[top]][j] < a[i][j]) { top--; } sus[i - 1][j] = stv[top] + 1; stv[++top] = i; } top = 0; stv[0] = n + 1; for (int i = n; i >= 1; i--) { while (top && a[stv[top]][j] < a[i][j]) { top--; } jos[i + 1][j] = stv[top] - 1; stv[++top] = i; } } for (int i = 2; i < n; i++) { for (int j = 2; j < m; j++) { if (1 < st[i][j] && st[i][j] <= j) { rows.push_back({i, st[i][j], j}); } if (dr[i][j] < m && j <= dr[i][j]) { rows.push_back({i, j, dr[i][j]}); } if (1 < sus[i][j] && sus[i][j] <= i) { cols.push_back({j, sus[i][j], i}); } if (jos[i][j] < n && i <= jos[i][j]) { cols.push_back({j, i, jos[i][j]}); } } } sort(rows.begin(), rows.end()); sort(cols.begin(), cols.end()); int pos = 0; for (int r2 = 1; r2 <= n; r2++) { for (int c2 = 1; c2 <= m; c2++) { KEKMAN it = {r2, 0, c2}; while (pos < (int) rows.size() && rows[pos] < it) { pos++; } if (pos < (int) rows.size() && rows[pos] == it) { int i = pos, j; while (pos + 1 < (int) rows.size() && rows[pos + 1] == it) { pos++; } j = pos; lx[r2][c2] = i; rx[r2][c2] = j; pos++; } else { lx[r2][c2] = -1; rx[r2][c2] = -1; } } } pos = 0; for (int c2 = 1; c2 <= m; c2++) { for (int r2 = 1; r2 <= n; r2++) { KEKMAN it = {c2, 0, r2}; while (pos < (int) cols.size() && cols[pos] < it) { pos++; } if (pos < (int) cols.size() && cols[pos] == it) { int i = pos, j; while (pos + 1 < (int) cols.size() && cols[pos + 1] == it) { pos++; } j = pos; ly[r2][c2] = i; ry[r2][c2] = j; pos++; } else { ly[r2][c2] = -1; ry[r2][c2] = -1; } } } for (int r = 1; r <= n; r++) { for (int c = 1; c <= m; c++) { if (lx[r][c] != -1 && ly[r][c] != -1) { for (int i = lx[r][c]; i <= rx[r][c]; i++) { int c1 = rows[i].l; for (int j = ly[r][c]; j <= ry[r][c]; j++) { int r1 = cols[j].l; check(r1, c1, r, c); } } } } } if (solutions.empty()) { return 0; } sort(solutions.begin(), solutions.end()); int sol = 1; for (int i = 1; i < (int) solutions.size(); i++) { sol += (solutions[i] != solutions[i - 1]); } return sol; }
#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...