Submission #635851

#TimeUsernameProblemLanguageResultExecution timeMemory
635851tabrRectangles (IOI19_rect)C++17
23 / 100
1596 ms367948 KiB
#include <bits/stdc++.h> using namespace std; #ifdef tabr #include "library/debug.cpp" #else #define debug(...) #endif struct dsu { vector<int> p; vector<int> sz; vector<int> mn; vector<int> mx; int n; dsu(int _n) : n(_n) { p = vector<int>(n); iota(p.begin(), p.end(), 0); sz = vector<int>(n, 1); mx = p; mn = p; } inline int get(int x) { if (p[x] == x) { return x; } else { return p[x] = get(p[x]); } } inline bool unite(int x, int y) { x = get(x); y = get(y); if (x == y) { return false; } p[x] = y; sz[y] += sz[x]; mn[y] = min(mn[y], mn[x]); mx[y] = max(mx[y], mx[x]); return true; } inline bool same(int x, int y) { return (get(x) == get(y)); } inline int size(int x) { return sz[get(x)]; } inline bool root(int x) { return (x == get(x)); } }; struct sparse { using T = int; int n; int h; vector<vector<T>> table; T op(T x, T y) { return min(x, y); } sparse(const vector<T> &v) { n = (int) v.size(); h = 32 - __builtin_clz(n); table.resize(h); table[0] = v; for (int j = 1; j < h; j++) { table[j].resize(n - (1 << j) + 1); for (int i = 0; i <= n - (1 << j); i++) { table[j][i] = op(table[j - 1][i], table[j - 1][i + (1 << (j - 1))]); } } } T get(int l, int r) { assert(l < r); int k = 31 - __builtin_clz(r - l); return op(table[k][l], table[k][r - (1 << k)]); } }; long long count_rectangles(vector<vector<int>> a) { int h = (int) a.size(); int w = (int) a[0].size(); vector<vector<int>> first_ng(h, vector<int>(w, h)); for (int j = 0; j < w; j++) { vector<int> s; for (int i = h - 1; i >= 0; i--) { while (!s.empty() && a[s.back()][j] < a[i][j]) { s.pop_back(); } if (!s.empty()) { first_ng[i][j] = s.back(); } s.emplace_back(i); } } debug(first_ng); long long res = 0; map<pair<int, int>, int> cnt; vector<vector<multiset<int>>> ng(w, vector<multiset<int>>(w)); for (int i = 1; i < h - 1; i++) { vector<vector<int>> bound(w); map<int, vector<int>> v; for (int j = 0; j < w; j++) { v[a[i][j]].emplace_back(j); } dsu uf(w); for (auto p : v) { for (int j : p.second) { if (j - 1 >= 0 && a[i][j] >= a[i][j - 1]) { uf.unite(j - 1, j); } if (j + 1 < w && a[i][j] >= a[i][j + 1]) { uf.unite(j + 1, j); } } for (int j : p.second) { if (uf.root(j) && uf.mn[j] > 0 && uf.mx[j] < w - 1) { bound[uf.mx[j]].emplace_back(uf.mn[j]); } } } sparse sp(first_ng[i - 1]); int up_last = 0; int down_last = 0; map<pair<int, int>, int> new_cnt; for (int j = 1; j < w - 1; j++) { if (a[i][j] >= a[i - 1][j]) { up_last = j; } if (a[i][j] >= a[i + 1][j]) { down_last = j; } for (int k : bound[j]) { new_cnt[make_pair(k, j)] = cnt[make_pair(k, j)]; if (up_last < k) { new_cnt[make_pair(k, j)]++; ng[k][j].emplace(sp.get(k, j + 1)); } new_cnt[make_pair(k, j)] -= (int) ng[k][j].count(i); ng[k][j].erase(i); if (down_last < k) { res += new_cnt[make_pair(k, j)]; } } } for (auto p : cnt) { if (!new_cnt.count(p.first)) { ng[p.first.first][p.first.second].clear(); } } swap(cnt, new_cnt); } return res; } #ifdef tabr int main() { ios::sync_with_stdio(false); cin.tie(0); debug(count_rectangles({{4, 8, 7, 5, 6}, {7, 4, 10, 3, 5}, {9, 7, 20, 14, 2}, {9, 14, 7, 3, 6}, {5, 7, 5, 2, 7}, {4, 5, 13, 5, 6}})); debug(count_rectangles({{5, 7, 5}, {9, 4, 7}, {9, 7, 20}, {7, 4, 10}, {4, 8, 7}})); return 0; } #endif
#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...