제출 #145170

#제출 시각아이디문제언어결과실행 시간메모리
145170jwvg0425Rectangles (IOI19_rect)C++17
72 / 100
5101 ms141620 KiB
#include "rect.h" #include <stdio.h> #include <vector> #include <queue> #include <algorithm> #include <iostream> #include <string> #include <bitset> #include <map> #include <set> #include <tuple> #include <string.h> #include <math.h> #include <random> #include <functional> #include <assert.h> #include <math.h> #include <stack> #define all(x) (x).begin(), (x).end() #define xx first #define yy second using namespace std; using i64 = long long int; using ii = pair<int, int>; using ii64 = pair<i64, i64>; int up[2505][2505]; int down[2505][2505]; bool visited[2505][2505]; int dx[] = { -1, 0, 1, 0 }; int dy[] = { 0, -1, 0, 1 }; i64 sub6(vector<vector<int>> a) { int n = a.size(); int m = a[0].size(); i64 ans = 0; for (int x = 1; x < n - 1; x++) { for (int y = 1; y < m - 1; y++) { if (visited[x][y] || a[x][y] == 1) continue; int lx = x, ly = y, rx = x, ry = y; int c = 0; queue<ii> q; q.emplace(x, y); visited[x][y] = true; while (!q.empty()) { auto now = q.front(); q.pop(); lx = min(now.xx, lx); ly = min(now.yy, ly); rx = max(now.xx, rx); ry = max(now.yy, ry); c++; for (int i = 0; i < 4; i++) { int nx = now.xx + dx[i]; int ny = now.yy + dy[i]; if (nx == 0 || nx == n - 1 || ny == 0 || ny == m - 1 || visited[nx][ny] || a[nx][ny] == 1) continue; visited[nx][ny] = true; q.emplace(nx, ny); } } bool ok = true; if (c != (rx - lx + 1) * (ry - ly + 1)) ok = false; for (int i = ly; i <= ry; i++) if (a[lx - 1][i] != 1 || a[rx + 1][i] != 1) ok = false; for (int i = lx; i <= rx; i++) if (a[i][ly - 1] != 1 || a[i][ry + 1] != 1) ok = false; if (ok) ans++; } } return ans; } i64 count_rectangles(vector<vector<int>> a) { int n = a.size(); int m = a[0].size(); i64 ans = 0; int amax = 0; for (int x = 0; x < n; x++) { for (int y = 0; y < m; y++) { amax = max(amax, a[x][y]); int yu = y - 1; int yd = y + 1; while (yd < m && a[x][yd] < a[x][y]) yd++; while (yu >= 0 && a[x][yu] < a[x][y]) yu--; down[x][y] = yd - y - 1; up[x][y] = y - yu - 1; } } if (amax == 1) return sub6(a); for (int l = 0; l < n - 2; l++) { vector<int> dnow(m, 987654321); vector<int> unow(m, 987654321); vector<int> maxv(m, 0); // 좌우에서 y별 최댓값값 for (int r = l + 2; r < n; r++) { vector<int> newup(m + 1, 0); vector<int> newdown(m + 1, 0); vector<int> delup(m + 1, 0); vector<int> deldown(m + 1, 0); vector<int> lrup(m + 1, 0); vector<int> lrdown(m + 1, 0); vector<bool> lr(m, 0); // l - r은 가능한지 vector<int> depth(m + 1, 0); for (int y = 0; y < m; y++) { dnow[y] = min(dnow[y], down[r - 1][y]); unow[y] = min(unow[y], up[r - 1][y]); maxv[y] = max(maxv[y], a[r - 1][y]); lr[y] = maxv[y] < a[l][y] && maxv[y] < a[r][y]; } int lru = 0, lrd = 0; vector<int> dval(m + 1, 0); vector<int> uval(m + 1, 0); for (int y = 0; y < m; y++) { uval[y] = min(unow[y], lru); if (lr[y]) lru++; else lru = 0; } for (int y = m - 1; y >= 0; y--) { dval[y] = min(dnow[y], lrd); if (lr[y]) lrd++; else lrd = 0; } for (int y = 0; y < m; y++) { if (uval[y] >= 1) { newup[y - uval[y]]++; delup[y - 1]++; } if (dval[y] >= 1) { newdown[y + 1]++; deldown[y + dval[y]]++; } } int d = 0; for (int y = 0; y < m; y++) { d += newup[y]; d -= delup[y]; depth[y] = d; } // (ypos, minvalue) stack<ii> s; for (int y = 1; y < m; y++) { for (int j = 0; j < newdown[y]; j++) s.emplace(y, 987654321); if (!s.empty()) { s.top().yy = min(s.top().yy, depth[y]); } for (int j = 0; j < deldown[y]; j++) { ii top = s.top(); int f = depth[top.xx - 1] + newup[top.xx]; ans += f - top.yy; s.pop(); if (!s.empty()) s.top().yy = min(s.top().yy, top.yy); } } } } 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...