#include <iostream>
#include <vector>
#include <string>
#include <math.h>
#include <cmath>
#include <iomanip>
#include <cstdio>
#include <algorithm>
#include <numeric>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <deque>
#include <bitset>
#include <cstring>
#include <unordered_map>
using namespace std;
typedef long long ll;
#include "rect.h"
ll n, m;
vector<int> f[2502][2502], d[2502][2502]; // f -- for [i][j], left, horizontal.
vector<pair<int, int>> can[2502][2502];
int h[2502];
ll t[2502];
vector<int> roll;
void add(int pos, int val){
// roll.push_back(pos);
pos++;
for(int i = pos; i < 2502; i += (i & -i))
t[i] += val;
}
int get(int pos){
pos++;
int ans = 0;
for(int i = pos; i > 0; i -= (i & -i))
ans += t[i];
return ans;
}
long long count_rectangles(vector<vector<int>> a){
n = a.size(), m = a[0].size();
for(int j = 0; j < m; j++){
vector<int> cur;
for(int i = 1; i < n; i++){
while(!cur.empty() && a[cur.back()][j] <= a[i - 1][j])
cur.pop_back();
cur.push_back(i - 1);
for(int k = (ll)(cur.size()) - 1; k >= 0; k--){
if(cur[k] != i - 1){
d[i][j].push_back(cur[k]);
}
if(a[cur[k]][j] >= a[i][j])
break;
}
}
}
for(int i = 0; i < n; i++){
vector<pair<int, int>> cur; // {length from the left horizontal, index above }
vector<pair<int, int>> temp; // {length from the left horizontal, index above }
vector<int> cur2;
for(int j = 1; j < m; j++){
while(!cur2.empty() && a[i][cur2.back()] <= a[i][j - 1])
cur2.pop_back();
cur2.push_back(j - 1);
for(int k = (ll)(cur2.size()) - 1; k >= 0; k--){
if(cur2[k] != j - 1){
f[i][j].push_back(cur2[k]);
}
if(a[i][cur2[k]] >= a[i][j])
break;
}
for(auto k: cur)
h[k.second] = -k.first;
for(auto k: d[i][j - 1]){
if(h[k] < 0)
h[k] = abs(h[k]) + 1;
else
h[k] = 1;
}
temp.clear();
for(auto k: d[i][j - 1]){
if(h[k] == 1)
temp.push_back({1, k});
}
for(auto i: cur){
if(h[i.second] > 1)
temp.push_back({h[i.second], i.second});
}
for(auto k: cur)
h[k.second] = 0;
can[i][j] = temp;
cur = temp;
}
for(int j = 0; j <= n; j++)
h[j] = 0;
}
ll ans = 0;
for(int j = 2; j < m; j++){
vector<pair<int, int>> cur; // {index to the left, length above }
for(int i = 2; i < n; i++){
for(auto k: cur)
h[k.first] = -k.second;
for(auto k: f[i - 1][j]){
if(h[k] < 0)
h[k] = abs(h[k]) + 1;
else
h[k] = 1;
}
for(auto k: cur)
if(h[k.first] < 0)
h[k.first] = 0;
cur.clear();
reverse(f[i - 1][j].begin(), f[i - 1][j].end());
for(auto k: f[i - 1][j]){
cur.push_back({k, h[k]});
}
int ind = (ll)(can[i][j].size()) - 1;
for(int k = 0; k < cur.size(); k++){
while(ind >= 0){ // maybe we can add that
if(j - 1 - can[i][j][ind].first <= cur[k].first){
add(n - 1 - can[i][j][ind].second, 1);
ind--;
}
else
break;
}
int cnt = get(n - 1 - (i - cur[k].second - 1));
ans += cnt;
}
for(int k = (ll)(can[i][j].size()) - 1; k > ind; k--){
add(n - 1 - can[i][j][k].second, -1);
}
}
for(int j = 0; j <= m; j++)
h[j] = 0;
}
return ans;
}
/*
3 5
4 8 7 20 6
10 8 9 2 999
9 7 20 14 2
5 7
1 1 1 1 1 0 1
1 0 1 0 0 0 1
1 1 1 0 1 1 0
1 0 1 1 1 0 1
1 1 0 0 0 1 0
*/
# | 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... |