Submission #769716

#TimeUsernameProblemLanguageResultExecution timeMemory
769716SanguineChameleonRectangles (IOI19_rect)C++17
59 / 100
5085 ms700884 KiB
#include "rect.h" #include <bits/stdc++.h> using namespace std; const int maxn = 2.5e3 + 20; int a[maxn][maxn]; int mx[maxn]; int streak[maxn]; vector<pair<int, int>> cand_left[maxn][maxn]; vector<pair<int, int>> cand_up[maxn][maxn]; vector<pair<int, int>> row_queries[maxn][maxn]; vector<pair<int, int>> col_queries[maxn][maxn]; int n, m; void add_left(int row, int lt, int rt) { if (lt > rt) { return; } row_queries[lt][rt].emplace_back(row, cand_left[row][lt].size()); cand_left[row][lt].emplace_back(rt - lt + 1, -1); } void find_left(int row) { vector<int> q; for (int i = 1; i <= m; i++) { while (!q.empty() && a[row][i] > a[row][q.back()]) { q.pop_back(); } if (!q.empty() && a[row][i] < a[row][q.back()]) { add_left(row, q.back() + 1, i - 1); } q.push_back(i); } q.clear(); for (int i = m; i >= 1; i--) { while (!q.empty() && a[row][i] > a[row][q.back()]) { q.pop_back(); } if (!q.empty()) { add_left(row, i + 1, q.back() - 1); } q.push_back(i); } } void add_up(int col, int lt, int rt) { if (lt > rt) { return; } col_queries[lt][rt].emplace_back(col, cand_up[lt][col].size()); cand_up[lt][col].emplace_back(rt - lt + 1, -1); } void find_up(int col) { vector<int> q; for (int i = 1; i <= n; i++) { while (!q.empty() && a[i][col] > a[q.back()][col]) { q.pop_back(); } if (!q.empty() && a[i][col] < a[q.back()][col]) { add_up(col, q.back() + 1, i - 1); } q.push_back(i); } q.clear(); for (int i = n; i >= 1; i--) { while (!q.empty() && a[i][col] > a[q.back()][col]) { q.pop_back(); } if (!q.empty()) { add_up(col, i + 1, q.back() - 1); } q.push_back(i); } } void solve_row() { for (int lt = 1; lt <= m; lt++) { for (int i = 1; i <= n; i++) { mx[i] = 0; } for (int rt = lt; rt <= m; rt++) { streak[n + 1] = 0; for (int i = n; i >= 1; i--) { mx[i] = max(mx[i], a[i][rt]); if (mx[i] < a[i][lt - 1] && mx[i] < a[i][rt + 1]) { streak[i] = streak[i + 1] + 1; } else { streak[i] = 0; } } for (auto q: row_queries[lt][rt]) { int row = q.first; int id = q.second; cand_left[row][lt][id].second = streak[row]; } } } } void solve_col() { for (int lt = 1; lt <= n; lt++) { for (int i = 1; i <= m; i++) { mx[i] = 0; } for (int rt = lt; rt <= n; rt++) { streak[m + 1] = 0; for (int i = m; i >= 1; i--) { mx[i] = max(mx[i], a[rt][i]); if (mx[i] < a[lt - 1][i] && mx[i] < a[rt + 1][i]) { streak[i] = streak[i + 1] + 1; } else { streak[i] = 0; } } for (auto q: col_queries[lt][rt]) { int col = q.first; int id = q.second; cand_up[lt][col][id].second = streak[col]; } } } } long long count_rectangles(vector<vector<int>> _a) { n = _a.size(); m = _a[0].size(); if (n < 3 || m < 3) { return 0; } for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { a[i][j] = _a[i - 1][j - 1]; } } for (int i = 1; i <= n; i++) { find_left(i); } for (int i = 1; i <= m; i++) { find_up(i); } solve_row(); solve_col(); int res = 0; for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { for (auto p1: cand_left[i][j]) { for (auto p2: cand_up[i][j]) { if (p1.second >= p2.first && p2.second >= p1.first) { res++; } } } } } return res; }
#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...