This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#ifndef LOCAL
#include "rect.h"
#endif // LOCAL
#include <bits/stdc++.h>
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define eb emplace_back
#define ar array
using namespace std;
typedef long long ll;
typedef pair<int, int> ii;
const int maxn = 2505;
int N, M;
vector<int> strow[maxn], stcol[maxn];
int lst_row[maxn][maxn], lst_col[maxn][maxn];
int cnt_row[maxn][maxn], cnt_col[maxn][maxn];
int bit[maxn];
void upd(int i, int v)
{
for(; i < maxn; i += i & -i)
bit[i] += v;
}
int sum(int i)
{
int res = 0;
for(; i; i -= i & -i)
res += bit[i];
return res;
}
ii get(int l, int r, int cur, int lst[maxn][maxn], int cnt[maxn][maxn])
{
if(lst[l][r] != cur - 1)
cnt[l][r] = 0;
++cnt[l][r]; lst[l][r] = cur;
return mp(r - l - 1, cnt[l][r]);
}
ll way(vector<ii> & row, vector<ii> & col)
{
for(auto & it : col) swap(it.fi, it.se);
ll res = 0;
sort(col.rbegin(), col.rend());
sort(row.rbegin(), row.rend());
int j = 0;
for(int i = 0; i < (int)row.size(); ++i){
while(j < (int)col.size() && col[j].fi >= row[i].fi){
upd(col[j].se, 1);
++j;
}
res += sum(row[i].se);
}
for(int i = 0; i < j; ++i)
upd(col[i].se, -1);
return res;
}
long long count_rectangles(std::vector<std::vector<int>> a)
{
N = a.size();
M = a[0].size();
for(int i = 0; i < N; ++i)
strow[i].eb(0);
for(int j = 0; j < M; ++j)
stcol[j].eb(0);
ll ans = 0;
for(int i = 0; i < N - 1; ++i){
for(int j = 0; j < M - 1; ++j){
///row
vector<ii> rows;
bool eq = false;
while(strow[i].size()){
int k = strow[i].back();
if(k < j && !eq) rows.eb(get(k, j + 1, i, lst_row, cnt_row));
if(a[i][k] == a[i][j + 1]) eq = true;
if(a[i][k] <= a[i][j + 1])
strow[i].pop_back();
else break;
}
strow[i].eb(j + 1);
///col
vector<ii> cols;
eq = false;
while(stcol[j].size()){
int k = stcol[j].back();
//if(i == 4 && j == 3) cerr << k << ' ';
if(k < i && !eq) cols.eb(get(k, i + 1, j, lst_col, cnt_col));
if(a[i + 1][j] == a[k][j]) eq = true;
if(a[k][j] <= a[i + 1][j])
stcol[j].pop_back();
else break;
}
stcol[j].eb(i + 1);
/*
if(i == 4 && j == 3){
for(auto & it : rows) cerr << it.fi << ' ' << it.se << '\n';
cerr << '\n';
for(auto & it : cols) cerr << it.fi << ' ' << it.se << '\n';
cerr << way(rows, cols);
}
*/
auto v = way(rows, cols);
ans += v;
if(v){
// cerr << i + 1 << ' ' << j + 1 << ' ' << v << '\n';
}
}
}
return ans;
}
#ifdef LOCAL
signed main(void)
{
ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#ifdef LOCAL
freopen("A.INP", "r", stdin);
freopen("A.OUT", "w", stdout);
#endif // LOCAL
int n, m; cin >> n >> m;
vector<vector<int>> a;
a.assign(n, vector<int>(m));
for(int i = 0; i < n; ++i){
for(int j = 0; j < m; ++j){
cin >> a[i][j];
}
}
cout << count_rectangles(a);
}
#endif
# | 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... |