Submission #1215337

#TimeUsernameProblemLanguageResultExecution timeMemory
1215337countlessRectangles (IOI19_rect)C++20
0 / 100
4 ms8776 KiB
#include "rect.h" #include <bits/stdc++.h> using namespace std; typedef long long ll; typedef long double ld; const int INF = 5e3; #define endl "\n" #define sp <<" "<< #define REP(i, a, b) for(ll i = a; i < b; i++) #define mp make_pair #define fast_io() ios_base::sync_with_stdio(false); cin.tie(NULL) #define all(x) (x).begin(), (x).end() struct stuff { short coll, colr, rowl, rowr; stuff(short coll = -INF, short colr = INF, short rowl = -INF, short rowr = INF) : coll(coll), colr(colr), rowl(rowl), rowr(rowr) {;;} static stuff merge(const stuff &a, const stuff &b) { return stuff{min(a.coll, b.coll), max(a.colr, b.colr), min(a.rowl, b.rowl), max(a.rowr, b.rowr)}; } static ll calc(const stuff &a) { // cerr << a.rowr - a.rowl - 1 sp a.colr - a.coll - 1 << endl; return ll(a.rowr - a.rowl - 1) * ll(a.colr - a.coll - 1); } }; const stuff nothing = stuff{INF, -INF, INF, -INF}; short n, m; int k; const int dr[4] = {0, 0, -1, 1}; const int dc[4] = {-1, 1, 0, 0}; inline bool in(const short &x, const short &y) { return (0 < x and x < n-1 and 0 < y and y < m-1); } inline ll encode(const ll &x, const ll &y, const ll &xx, const ll &yy) { return ((x<<48)|(y<<32)|(xx<<16)|yy); } unordered_set<ll> vis; ll count_rectangles(vector<vector<int>> a) { n = a.size(), m = a[0].size(), k = n * m; vector<vector<stuff>> base(n, vector<stuff>(m)); vis.reserve(1 << 20); ll ans = 0; vector<pair<int, int>> ts(k); vector<int> st; for (short i = 0; i < n; i++) { st.clear(); for (short j = 0; j < m; j++) { while (!st.empty() and a[i][st.back()] <= a[i][j]) { st.pop_back(); } if (!st.empty()) { base[i][j].rowl = st.back(); } st.push_back(j); } st.clear(); for (short j = m-1; j >= 0; j--) { while (!st.empty() and a[i][st.back()] <= a[i][j]) { st.pop_back(); } if (!st.empty()) { base[i][j].rowr = st.back(); } st.push_back(j); int ind = i * m + j; ts[ind] = {a[i][j], ind}; } } for (short i = 0; i < m ; i++) { st.clear(); for (short j = 0; j < n; j++) { while (!st.empty() and a[st.back()][i] <= a[j][i]) { st.pop_back(); } if (!st.empty()) { base[j][i].coll = st.back(); } st.push_back(j); } st.clear(); for (short j = n-1; j >= 0; j--) { while (!st.empty() and a[st.back()][i] <= a[j][i]) { st.pop_back(); } if (!st.empty()) { base[j][i].colr = st.back(); } st.push_back(j); } } sort(all(ts), [&](const auto &a, const auto &b) -> bool { return a.first < b.first; }); vector<int> par(k), siz(k, 1); vector<bool> vs(k, false); iota(all(par), 0); auto find = [&](auto &&find, int u) -> int { if (u == par[u]) return u; return par[u] = find(find, par[u]); }; auto unite = [&](int u, int v) -> void { u = find(find, u), v = find(find, v); if (u == v) return; // if (siz[u] < siz[v]) swap(u, v); par[v] = u; siz[u] += siz[v]; int ur = u / m, uc = u % m; int vr = u / m, vc = u % m; base[ur][uc] = stuff::merge(base[ur][uc], base[vr][vc]); return; }; auto ensure = [&](int u) -> bool { int ur = u / m, uc = u % m; // cerr << ur sp uc sp stuff::calc(base[ur][uc]) sp siz[u] << endl; return stuff::calc(base[ur][uc]) <= siz[u]; }; auto check = [&](int r, int c) -> bool { return 0 < r and r < n-1 and 0 < c and c < m-1; }; for (int i = 0; i < k; i++) { int hash = ts[i].second; int r = hash / m, c = hash % m; if (!check(r, c)) continue; for (int j = 0; j < 4; j++) { int nr = r + dr[j], nc = c + dc[j]; if (check(nr, nc) and vs[nr * m + nc]) { // cerr << "un" sp nr sp nc << endl; unite(hash, nr * m + nc); } } if (ensure(find(find, hash))) ans++; vs[hash] = true; } return ans; } // int main() { // int n, m; cin >> n >> m; // vector<vector<int>> a(n, vector<int>(m)); // REP(i, 0, n) { // REP(j, 0, m) { // cin >> a[i][j]; // } // } // cout << count_rectangles(a) << endl; // }
#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...