This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include<bits/stdc++.h>
#include "rect.h"
using namespace std;
typedef long long llint;
typedef pair <int, int> pi;
const int MAXN = 2505;
const int INF = 1000000007;
int n, m;
int a[MAXN][MAXN];
int lef[MAXN][MAXN], rig[MAXN][MAXN], upp[MAXN][MAXN], dwn[MAXN][MAXN];
vector <int> valr[MAXN][MAXN], valc[MAXN][MAXN];
vector < pair <pi, pi> > sol;
void precompute_row (int r) {
vector <int> st;
vector <pi> seg;
for (int c = 0; c < m; c++) {
while (!st.empty() && a[r][st.back()] <= a[r][c]) st.pop_back();
lef[r][c] = (st.empty() ? -1 : st.back());
st.push_back(c);
}
st.clear();
for (int c = m - 1; c >= 0; c--) {
while (!st.empty() && a[r][st.back()] <= a[r][c]) st.pop_back();
rig[r][c] = (st.empty() ? -1 : st.back());
st.push_back(c);
}
for (int c = 0; c < m; c++) {
if (lef[r][c] != -1 && rig[r][c] != -1) seg.push_back({lef[r][c] + 1, rig[r][c] - 1});
}
sort(seg.begin(), seg.end());
seg.erase(unique(seg.begin(), seg.end()), seg.end());
for (auto par : seg) {
valr[par.first][par.second].push_back(r);
}
}
void precompute_col (int c) {
vector <int> st;
vector <pi> seg;
for (int r = 0; r < n; r++) {
while (!st.empty() && a[st.back()][c] <= a[r][c]) st.pop_back();
upp[r][c] = (st.empty() ? -1 : st.back());
st.push_back(r);
}
st.clear();
for (int r = n - 1; r >= 0; r--) {
while (!st.empty() && a[st.back()][c] <= a[r][c]) st.pop_back();
dwn[r][c] = (st.empty() ? -1 : st.back());
st.push_back(r);
}
for (int r = 0; r < n; r++) {
if (upp[r][c] != -1 && dwn[r][c] != -1) seg.push_back({upp[r][c] + 1, dwn[r][c] - 1});
}
sort(seg.begin(), seg.end());
seg.erase(unique(seg.begin(), seg.end()), seg.end());
for (auto par : seg) {
valc[par.first][par.second].push_back(c);
}
}
inline int upit_row (int r, int c1, int c2) {
return upper_bound(valr[c1][c2].begin(), valr[c1][c2].end(), r) - valr[c1][c2].begin();
}
inline int sum_row (int r1, int r2, int c1, int c2) {
if (r1 == 0) return upit_row(r2, c1, c2);
return upit_row(r2, c1, c2) - upit_row(r1 - 1, c1, c2);
}
inline int upit_col (int c, int r1, int r2) {
return upper_bound(valc[r1][r2].begin(), valc[r1][r2].end(), c) - valc[r1][r2].begin();
}
inline int sum_col (int r1, int r2, int c1, int c2) {
if (c1 == 0) return upit_col(c2, r1, r2);
return upit_col(c2, r1, r2) - upit_col(c1 - 1, r1, r2);
}
bool check (int r1, int r2, int c1, int c2) {
return sum_row(r1, r2, c1, c2) == r2 - r1 + 1 && sum_col(r1, r2, c1, c2) == c2 - c1 + 1;
}
llint count_rectangles (vector<vector<int>> A) {
n = A.size(), m = A[0].size();
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
a[i][j] = A[i][j];
}
}
for (int r = 0; r < n; r++) precompute_row(r);
for (int c = 0; c < m; c++) precompute_col(c);
for (int r = 1; r < n - 1; r++) {
for (int c = 1; c < m - 1; c++) {
if (lef[r][c] != -1 && rig[r][c] != -1 && upp[r][c] != -1 && dwn[r][c] != -1) {
if (check(upp[r][c] + 1, dwn[r][c] - 1, lef[r][c] + 1, rig[r][c] - 1)) {
sol.push_back({{upp[r][c] + 1, dwn[r][c] - 1}, {lef[r][c] + 1, rig[r][c] - 1}});
}
}
}
}
sort(sol.begin(), sol.end());
sol.erase(unique(sol.begin(), sol.end()), sol.end());
return sol.size();
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |