제출 #223689

#제출 시각아이디문제언어결과실행 시간메모리
223689rama_pangRectangles (IOI19_rect)C++14
100 / 100
4225 ms834932 KiB
#include "rect.h" #include <bits/stdc++.h> using namespace std; class FenwickTree { // Suffix Sum private: int sz; vector<int> tree; public: FenwickTree() {} FenwickTree(int n) : sz(n) { tree.assign(sz, 0); } void Update(int p, int x) { for (int i = (sz - p - 1) + 1; i <= sz; i += (i & -i)) { tree[i - 1] += x; } } int Query(int p) { int res = 0; for (int i = (sz - p - 1) + 1; i > 0; i -= (i & -i)) { res += tree[i - 1]; } return res; } }; struct event_t { int type; int r2, c2; event_t() {} event_t(int t, int r, int c) : type(t), r2(r), c2(c) {} bool operator < (const event_t &o) const { return make_pair(r2, type) < make_pair(o.r2, o.type); } }; vector<pair<int, int>> get_pairs(vector<int> a) { int n = a.size(); vector<int> L(n, -1), R(n, n); { // Find the nearest value greater than a[i] on its left and right stack<int> s; for (int i = 0; i < n; i++) { while (!s.empty() && a[s.top()] <= a[i]) s.pop(); if (!s.empty()) L[i] = s.top(); s.emplace(i); } while (!s.empty()) s.pop(); for (int i = n - 1; i >= 0; i--) { while (!s.empty() && a[s.top()] <= a[i]) s.pop(); if (!s.empty()) R[i] = s.top(); s.emplace(i); } } vector<pair<int, int>> pairs; // valid pairs for (int i = 0; i < n; i++) { if (L[i] == -1 || R[i] == n) continue; pairs.emplace_back(L[i] + 1, R[i] - 1); } sort(begin(pairs), end(pairs)); pairs.resize(unique(begin(pairs), end(pairs)) - begin(pairs)); return pairs; } long long count_rectangles(vector<vector<int>> a) { int n = a.size(), m = a[0].size(); long long ans = 0; // valid pairs where (i, j) is one of its cell in the pairs vector<vector<vector<int>>> go_r(n, vector<vector<int>>(m)); vector<vector<vector<int>>> go_d(n, vector<vector<int>>(m)); { // Find valid pairs for each row and column // Find valid pairs in each row for (int i = 1; i < n - 1; i++) { vector<pair<int, int>> pairs = get_pairs(a[i]); for (auto j : pairs) { go_r[i][j.first].emplace_back(j.second); } } // Find valid pairs in each column for (int i = 1; i < m - 1; i++) { vector<int> cur; for (int j = 0; j < n; j++) { cur.emplace_back(a[j][i]); } vector<pair<int, int>> pairs = get_pairs(cur); for (auto j : pairs) { go_d[j.first][i].emplace_back(j.second); } } } // how many valid pairs (c1, c2) in the bottomside of current row vector<vector<pair<int, int>>> span_r(m, vector<pair<int, int>>(m, {-1, -1})); // (row start, row end) // how many valid pairs (r1, r2) in the rightside of current column vector<vector<pair<int, int>>> span_d(n, vector<pair<int, int>>(n, {-1, -1})); // (column start, column end) FenwickTree BIT(m); for (int r1 = n - 1; r1 >= 0; r1--) { for (int c1 = m - 1; c1 >= 0; c1--) { { // Process valid pairs which originated from (r1, c1) for (auto c2 : go_r[r1][c1]) { if (span_r[c1][c2].first == r1 + 1) { // we can extend span_r[c1][c2].first = r1; } else { // we must start anew span_r[c1][c2] = {r1, r1}; } } for (auto r2 : go_d[r1][c1]) { if (span_d[r1][r2].first == c1 + 1) { // we can extend span_d[r1][r2].first = c1; } else { // we must start anew span_d[r1][r2] = {c1, c1}; } } } vector<event_t> events; // (type, (r2, c2)) type = 0 for insertion, type = 1 for query { // Process each valid pair sorted by r2 for (auto r2 : go_d[r1][c1]) { events.emplace_back(0, r2, span_d[r1][r2].second); } for (auto c2 : go_r[r1][c1]) { events.emplace_back(1, span_r[c1][c2].second, c2); } sort(begin(events), end(events)); } for (auto event : events) { if (event.type == 0) { // insert new column valid pair BIT.Update(event.c2, +1); } else { // query for number of rectangles current row valid pair can form with ans += BIT.Query(event.c2); } } // Undo all updates for (auto event : events) { if (event.type == 0) { BIT.Update(event.c2, -1); } } } } 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...