Submission #844763

#TimeUsernameProblemLanguageResultExecution timeMemory
844763qthang2k11Rectangles (IOI19_rect)C++17
100 / 100
1990 ms564236 KiB
// [+] https://oj.uz/submission/286084 #include "rect.h" #include <bits/stdc++.h> using namespace std; using ll = long long; const int N = 2505; int lh[N], rh[N], lw[N], rw[N], a[N][N]; pair<int, int> range[N][N]; enum class EventType { add, get }; struct Event { EventType type; int r, c; Event() = default; Event(EventType type, int r, int c): type(type), r(r), c(c) {} bool operator < (const Event &other) const { return tie(r, type) < tie(other.r, other.type); } }; vector<Event> events[N][N]; struct FenwickTree { int BIT[N], n = N - 1, all = 0; FenwickTree() = default; FenwickTree(int n): n(n) {} void update(int x, int w) { for (; x <= n; x += x & -x) BIT[x] += w; all += w; } int pref(int x) { int ans = 0; for (; x > 0; x -= x & -x) ans += BIT[x]; return ans; } int suff(int x) { return all - pref(x - 1); } } cnt; ll count_rectangles(vector<vector<int>> b) { int m = b.size(), n = b[0].size(); for (int i = 1; i <= m; i++) for (int j = 1; j <= n; j++) a[i][j] = b[i - 1][j - 1]; for (int i = 1; i <= n; i++) for (int j = i; j <= n; j++) range[i][j] = {-1, -1}; for (int i = 1; i <= m; i++) { for (int j = 1; j <= n; j++) { lw[j] = j - 1; while (lw[j] > 0 && a[i][j] >= a[i][lw[j]]) lw[j] = lw[lw[j]]; } for (int j = n; j > 0; j--) { rw[j] = j + 1; while (rw[j] <= n && a[i][j] >= a[i][rw[j]]) rw[j] = rw[rw[j]]; } for (int j = 1; j <= n; j++) { int l = lw[j] + 1, r = rw[j] - 1; if (1 < l && l <= r && r < n && range[l][r].second != i) { if (range[l][r].second == i - 1) range[l][r].second++; else range[l][r] = {i, i}; int len = range[l][r].second - range[l][r].first + 1; events[i][r].emplace_back(EventType::get, len, r - l + 1); } } } for (int i = 1; i <= m; i++) for (int j = i; j <= m; j++) range[i][j] = {-1, -1}; for (int j = 1; j <= n; j++) { for (int i = 1; i <= m; i++) { lh[i] = i - 1; while (lh[i] > 0 && a[i][j] >= a[lh[i]][j]) lh[i] = lh[lh[i]]; } for (int i = m; i > 0; i--) { rh[i] = i + 1; while (rh[i] <= m && a[i][j] >= a[rh[i]][j]) rh[i] = rh[rh[i]]; } for (int i = 1; i <= m; i++) { int l = lh[i] + 1, r = rh[i] - 1; if (1 < l && l <= r && r < m && range[l][r].second != j) { if (range[l][r].second == j - 1) range[l][r].second++; else range[l][r] = {j, j}; int len = range[l][r].second - range[l][r].first + 1; events[r][j].emplace_back(EventType::add, r - l + 1, len); } } } ll ans = 0; for (int i = 1; i <= m; i++) { for (int j = 1; j <= n; j++) { auto &events = ::events[i][j]; sort(events.begin(), events.end()); for (const auto &event: events) { if (event.type == EventType::add) { cnt.update(event.c, +1); } else { ans += cnt.suff(event.c); } } for (const auto &event: events) if (event.type == EventType::add) cnt.update(event.c, -1); } } return ans; } #ifdef LOCAL int main() { int n, m; cin >> n >> m; vector<vector<int>> a(n, vector<int>(m)); for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { cin >> a[i][j]; } } long long result = count_rectangles(a); cout << result; 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...