Submission #811010

#TimeUsernameProblemLanguageResultExecution timeMemory
811010dxz05Rectangles (IOI19_rect)C++17
72 / 100
5087 ms469780 KiB
#pragma GCC optimize("Ofast,O3,unroll-loops") #pragma GCC target("avx,avx2") #include "rect.h" #include <bits/stdc++.h> using namespace std; vector<pair<int, int>> find_borders(const vector<int> &a){ int n = (int) a.size(); stack<int> st; vector<int> l(n), r(n); for (int i = 0; i < n; i++){ while (!st.empty() && a[st.top()] < a[i]) st.pop(); l[i] = (st.empty() ? -1 : st.top()); st.push(i); } while (!st.empty()) st.pop(); for (int i = n - 1; i >= 0; i--){ while (!st.empty() && a[st.top()] < a[i]) st.pop(); r[i] = (st.empty() ? n : st.top()); st.push(i); } vector<pair<int, int>> ans; set<pair<int, int>> s1; // (i, r[i]) set<pair<int, int>> s2; // (r[i], i) for (int j = 0; j < n; j++){ while (!s2.empty()){ int i = s2.begin()->second; if (r[i] < j){ s1.erase(make_pair(i, r[i])); s2.erase(make_pair(r[i], i)); } else { break; } } assert(s1.size() == s2.size()); auto it = s1.end(); while (true){ if (it == s1.begin()) break; it--; int i = it->first; if (i < l[j]) break; if (i + 1 < j) ans.emplace_back(i + 1, j - 1); } s1.emplace(j, r[j]); s2.emplace(r[j], j); } return ans; } const int MaxN = 2502; vector<int> ind[MaxN][MaxN], val[MaxN][MaxN]; int cnt[MaxN * MaxN]; long long count_rectangles(vector<vector<int>> A) { int n = (int) A.size(), m = (int) A[0].size(); for (int i = 1; i + 1 < n; i++){ vector<pair<int, int>> f = find_borders(A[i]); for (auto [l, r] : f){ ind[l][r].push_back(i); } } for (int j = 1; j + 1 < m; j++){ vector<int> col(n); for (int i = 0; i < n; i++) col[i] = A[i][j]; vector<pair<int, int>> f = find_borders(col); for (auto [l, r] : f){ val[r][j].push_back(l * n + r); } } long long ans = 0; for (int l = 1; l < m - 1; l++) for (int r = l; r < m - 1; r++){ int sz = (int) ind[l][r].size(); for (int ii = 0; ii < sz; ii++){ int x = ind[l][r][ii]; if (ii > 0 && ind[l][r][ii - 1] == x - 1) continue; unordered_set<int> used_values; for (int jj = ii; jj < sz; jj++){ int y = ind[l][r][jj]; if (y - x != jj - ii) break; for (int j = l; j <= r; j++){ for (int v : val[y][j]){ if (v / n < x) continue; cnt[v]++; if (cnt[v] == r - l + 1) ans++; used_values.insert(v); } } } for (int v : used_values){ cnt[v] = 0; } } } 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...