제출 #1107910

#제출 시각아이디문제언어결과실행 시간메모리
1107910SharkyRectangles (IOI19_rect)C++17
100 / 100
3957 ms1002096 KiB
#include "rect.h" #include <bits/stdc++.h> using namespace std; using ll = long long; vector<array<int, 2>> ed[2510]; vector<pair<int, int>> qr[2510]; ll fen[2510]; void upd(int u, int k) { for (; u <= 2500; u += (u & -u)) fen[u] += (ll) k; } ll query(int u) { ll res = 0; for (; u; u -= (u & -u)) res += fen[u]; return res; } ll count_rectangles(std::vector<std::vector<int32_t>> inp) { int n = inp.size(), m = inp[0].size(); ll ans = 0; vector<vector<int>> a(n+1, vector<int> (m+1)); for (int i = 1; i <= n; i++) for (int j = 1; j <= m; j++) a[i][j] = inp[i-1][j-1]; vector<vector<vector<int>>> h(m+1, vector<vector<int>> (m+1)); vector<vector<vector<int>>> v(n+1, vector<vector<int>> (n+1)); for (int i = 1; i <= n; i++) { stack<int> st; for (int j = 1; j <= m; j++) { bool eq = 0; while (!st.empty() && a[i][st.top()] <= a[i][j]) { if (st.top() + 1 < j && !eq) h[st.top() + 1][j - 1].push_back(i); if (a[i][st.top()] == a[i][j]) eq = true; st.pop(); } if (!st.empty() && st.top() + 1 < j && !eq) h[st.top() + 1][j - 1].push_back(i); st.push(j); } } for (int j = 1; j <= m; j++) { stack<int> st; for (int i = 1; i <= n; i++) { bool eq = 0; while (!st.empty() && a[st.top()][j] <= a[i][j]) { if (st.top() + 1 < i && !eq) v[st.top() + 1][i - 1].push_back(j); if (a[st.top()][j] == a[i][j]) eq = true; st.pop(); } if (!st.empty() && st.top() + 1 < i && !eq) v[st.top() + 1][i - 1].push_back(j); st.push(i); } } vector<vector<vector<array<int, 3>>>> rrect(n+1, vector<vector<array<int, 3>>> (m+1)); vector<vector<vector<array<int, 3>>>> crect(n+1, vector<vector<array<int, 3>>> (m+1)); for (int c1 = 1; c1 <= m; c1++) { for (int c2 = c1; c2 <= m; c2++) { vector<pair<int, int>> pr; for (int& row : h[c1][c2]) { // printf("strip: row = %d, columns = %d, %d\n", row, c1, c2); if (pr.empty() || pr.back().second + 1 != row) pr.push_back({row, row}); else pr.back().second++; } for (auto& [lb, rb] : pr) for (int i = lb; i <= rb; i++) crect[i][c1].push_back({c2, i, rb}); } } h.clear(); for (int r1 = 1; r1 <= n; r1++) { for (int r2 = r1; r2 <= n; r2++) { vector<pair<int, int>> pr; for (int& col : v[r1][r2]) { // printf("strip: column = %d, rows = %d, %d\n", col, r1, r2); if (pr.empty() || pr.back().second + 1 != col) pr.push_back({col, col}); else pr.back().second++; } for (auto& [lb, rb] : pr) for (int i = lb; i <= rb; i++) rrect[r1][i].push_back({r2, i, rb}); } } v.clear(); for (int r1 = 1; r1 <= n; r1++) { for (int c1 = 1; c1 <= m; c1++) { vector<int> crit; for (auto& [r2, lb, rb] : rrect[r1][c1]) { crit.push_back(r2); qr[r2].push_back({lb, rb}); } for (auto& [c2, lb, rb] : crect[r1][c1]) { crit.push_back(lb); crit.push_back(rb + 1); ed[lb].push_back({1, c2}); ed[rb + 1].push_back({0, c2}); } sort(crit.begin(), crit.end()); crit.erase(unique(crit.begin(), crit.end()), crit.end()); for (auto& ti : crit) { for (auto& [x, y] : ed[ti]) { if (x) upd(y, 1); else upd(y, -1); } for (auto& [x, y] : qr[ti]) ans += query(y) - query(x-1); // cout << r1 << " " << c1 << " " << ans << '\n'; ed[ti].clear(); qr[ti].clear(); } } } 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...