Submission #737682

#TimeUsernameProblemLanguageResultExecution timeMemory
737682rnl42Rectangles (IOI19_rect)C++14
10 / 100
426 ms106308 KiB
#include "rect.h" #include <stack> #include <algorithm> using namespace std; enum { TOP = 0, BOTTOM = 1, LEFT = 2, RIGHT = 3, }; struct Case { int next[4] = {-1, -1, -1, -1}; bool hasrect() { return next[0] != -1 && next[1] != -1 && next[2] != -1 && next[3] != -1; } }; struct Rect1d { int a, b, w = 1; bool operator<(const Rect1d& other) const { return a == other.a ? b < other.b : a < other.a; } bool operator==(const Rect1d& other) const { return a == other.a && b == other.b; } }; struct Rectangle { int r1, c1, r2, c2; bool operator<(const Rectangle& other) const { if (r1 != other.r1) return r1 < other.r1; if (c1 != other.c1) return c1 < other.c1; if (r2 != other.r2) return r2 < other.r2; if (c2 != other.c2) return c2 < other.c2; return false; } bool operator==(const Rectangle& other) const { return r1 == other.r1 && c1 == other.c1 && r2 == other.r2 && c2 == other.c2; } }; long long count_rectangles(vector<vector<int>> A) { const int R = A.size(), C = A[0].size(); vector<vector<Case>> cases(R, vector<Case>(C)); stack<int> dec_seq; for (int r = 0; r < R; r++) { for (int c = 0; c < C; c++) { while (!dec_seq.empty() && A[r][dec_seq.top()] < A[r][c]) { dec_seq.pop(); } if (!dec_seq.empty() && A[r][dec_seq.top()] > A[r][c]) cases[r][c].next[LEFT] = dec_seq.top(); dec_seq.push(c); } while (!dec_seq.empty()) dec_seq.pop(); for (int c = C-1; c >= 0; c--) { while (!dec_seq.empty() && A[r][dec_seq.top()] <= A[r][c]) { dec_seq.pop(); } if (!dec_seq.empty()) cases[r][c].next[RIGHT] = dec_seq.top(); dec_seq.push(c); } while (!dec_seq.empty()) dec_seq.pop(); } for (int c = 0; c < C; c++) { for (int r = 0; r < R; r++) { while (!dec_seq.empty() && A[dec_seq.top()][c] < A[r][c]) { dec_seq.pop(); } if (!dec_seq.empty() && A[dec_seq.top()][c] > A[r][c]) cases[r][c].next[TOP] = dec_seq.top(); dec_seq.push(r); } while (!dec_seq.empty()) dec_seq.pop(); for (int r = R-1; r >= 0; r--) { while (!dec_seq.empty() && A[dec_seq.top()][c] <= A[r][c]) { dec_seq.pop(); } if (!dec_seq.empty()) cases[r][c].next[BOTTOM] = dec_seq.top(); dec_seq.push(r); } while (!dec_seq.empty()) dec_seq.pop(); } vector<Rectangle> rects; for (int r = 0; r < R; r++) { for (int c = 0; c < C; c++) { if (cases[r][c].hasrect()) { rects.push_back({cases[r][c].next[TOP]+1, cases[r][c].next[LEFT]+1, cases[r][c].next[BOTTOM]-1, cases[r][c].next[RIGHT]-1}); } } } sort(rects.begin(), rects.end()); rects.resize(unique(rects.begin(), rects.end()) - rects.begin()); vector<vector<Rect1d>> rect1ds[2]; rect1ds[0].resize(R); rect1ds[1].resize(C); for (int r = 0; r < R; r++) { for (int c = 0; c < C; c++) { if (cases[r][c].next[LEFT] != -1 && cases[r][c].next[RIGHT] != -1) { Rect1d newr = {cases[r][c].next[LEFT]+1, cases[r][c].next[RIGHT]-1}; if (r > 0) { auto it = lower_bound(rect1ds[0][r-1].begin(), rect1ds[0][r-1].end(), newr); if (it != rect1ds[0][r-1].end() && *it == newr) { newr.w = 1+it->w; } } rect1ds[0][r].push_back(newr); } } sort(rect1ds[0][r].begin(), rect1ds[0][r].end()); } for (int c = 0; c < C; c++) { for (int r = 0; r < R; r++) { if (cases[r][c].next[TOP] != -1 && cases[r][c].next[BOTTOM] != -1) { Rect1d newr = {cases[r][c].next[TOP]+1, cases[r][c].next[BOTTOM]-1}; if (c > 0) { auto it = lower_bound(rect1ds[1][c-1].begin(), rect1ds[1][c-1].end(), newr); if (it != rect1ds[1][c-1].end() && *it == newr) { newr.w = 1+it->w; } } rect1ds[1][c].push_back(newr); } } sort(rect1ds[1][c].begin(), rect1ds[1][c].end()); } int ans = 0; for (auto& r : rects) { auto& v = rect1ds[0][r.r2]; auto it = lower_bound(v.begin(), v.end(), Rect1d{r.c1, r.c2}); if (it != v.end() && it->w >= r.r2-r.r1+1) { auto& v = rect1ds[1][r.c2]; auto it = lower_bound(v.begin(), v.end(), Rect1d{r.r1, r.r2}); if (it != v.end() && it->w >= r.c2-r.c1+1) { ans++; } } } return ans; }
#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...