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 "rect.h"
#include <bits/stdc++.h>
using namespace std;
const int maxn = 2.5e3 + 20;
int a[maxn][maxn];
int mx[maxn];
int streak[maxn];
vector<pair<int, int>> cand_left[maxn][maxn];
vector<pair<int, int>> cand_up[maxn][maxn];
vector<pair<int, int>> row_queries[maxn][maxn];
vector<pair<int, int>> col_queries[maxn][maxn];
int n, m;
void add_left(int row, int lt, int rt) {
if (lt > rt) {
return;
}
row_queries[lt][rt].emplace_back(row, cand_left[row][lt].size());
cand_left[row][lt].emplace_back(rt - lt + 1, -1);
}
void find_left(int row) {
vector<int> q;
for (int i = 1; i <= m; i++) {
while (!q.empty() && a[row][i] > a[row][q.back()]) {
q.pop_back();
}
if (!q.empty() && a[row][i] < a[row][q.back()]) {
add_left(row, q.back() + 1, i - 1);
}
q.push_back(i);
}
q.clear();
for (int i = m; i >= 1; i--) {
while (!q.empty() && a[row][i] > a[row][q.back()]) {
q.pop_back();
}
if (!q.empty()) {
add_left(row, i + 1, q.back() - 1);
}
q.push_back(i);
}
}
void add_up(int col, int lt, int rt) {
if (lt > rt) {
return;
}
col_queries[lt][rt].emplace_back(col, cand_up[lt][col].size());
cand_up[lt][col].emplace_back(rt - lt + 1, -1);
}
void find_up(int col) {
vector<int> q;
for (int i = 1; i <= n; i++) {
while (!q.empty() && a[i][col] > a[q.back()][col]) {
q.pop_back();
}
if (!q.empty() && a[i][col] < a[q.back()][col]) {
add_up(col, q.back() + 1, i - 1);
}
q.push_back(i);
}
q.clear();
for (int i = n; i >= 1; i--) {
while (!q.empty() && a[i][col] > a[q.back()][col]) {
q.pop_back();
}
if (!q.empty()) {
add_up(col, i + 1, q.back() - 1);
}
q.push_back(i);
}
}
void solve_row() {
for (int lt = 1; lt <= m; lt++) {
for (int i = 1; i <= n; i++) {
mx[i] = 0;
}
for (int rt = lt; rt <= m; rt++) {
streak[n + 1] = 0;
for (int i = n; i >= 1; i--) {
mx[i] = max(mx[i], a[i][rt]);
if (mx[i] < a[i][lt - 1] && mx[i] < a[i][rt + 1]) {
streak[i] = streak[i + 1] + 1;
}
else {
streak[i] = 0;
}
}
for (auto q: row_queries[lt][rt]) {
int row = q.first;
int id = q.second;
cand_left[row][lt][id].second = streak[row];
}
}
}
}
void solve_col() {
for (int lt = 1; lt <= n; lt++) {
for (int i = 1; i <= m; i++) {
mx[i] = 0;
}
for (int rt = lt; rt <= n; rt++) {
streak[m + 1] = 0;
for (int i = m; i >= 1; i--) {
mx[i] = max(mx[i], a[rt][i]);
if (mx[i] < a[lt - 1][i] && mx[i] < a[rt + 1][i]) {
streak[i] = streak[i + 1] + 1;
}
else {
streak[i] = 0;
}
}
for (auto q: col_queries[lt][rt]) {
int col = q.first;
int id = q.second;
cand_up[lt][col][id].second = streak[col];
}
}
}
}
long long count_rectangles(vector<vector<int>> _a) {
n = _a.size();
m = _a[0].size();
if (n < 3 || m < 3) {
return 0;
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
a[i][j] = _a[i - 1][j - 1];
}
}
for (int i = 1; i <= n; i++) {
find_left(i);
}
for (int i = 1; i <= m; i++) {
find_up(i);
}
solve_row();
solve_col();
int res = 0;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
for (auto p1: cand_left[i][j]) {
for (auto p2: cand_up[i][j]) {
if (p1.second >= p2.first && p2.second >= p1.first) {
res++;
}
}
}
}
}
return res;
}
# | 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... |