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 ll;
typedef pair<short, short> pii;
#define fi first
#define se second
#define mp make_pair
const int N = 2505;
short lef[N][N];
short rig[N][N];
short up[N][N];
short dow[N][N];
vector<pii> rr[N][N];
vector<pii> dd[N][N];
struct segtree{
short n;
int mode;
vector<short> vals;
void init(short sz, short md){
n = sz;
mode = md;
vals.resize(n * 2);
}
void upd(short x, short v){
if(mode == 0 && v == -1)
v = 5005;
x += n;
vals[x] = v;
x >>= 1;
while(x > 0){
if(mode == 0) vals[x] = min(vals[x * 2], vals[x * 2 + 1]);
else vals[x] = max(vals[x * 2], vals[x * 2 + 1]);
x >>= 1;
}
}
short get(int l, int r){
l += n;
r += n;
short sol = 5005;
if(mode == 1) sol = -1;
while(l <= r){
if((l & 1)){
if(mode == 0) sol = min(sol, vals[l]);
else sol = max(sol, vals[l]);
l ++ ;
}
if(!(r & 1)){
if(mode == 0) sol = min(sol, vals[r]);
else sol = max(sol, vals[r]);
r -- ;
}
l >>= 1;
r >>= 1;
}
return sol;
}
};
segtree L[N], R[N], U[N], D[N];
bool is_valid(short i1, short j1, short i2, short j2){
if(D[i1].get(j1 + 1 ,j2 - 1) < i2) return false;
if(U[i2].get(j1 + 1, j2 - 1) > i1) return false;
if(R[j1].get(i1 + 1, i2 - 1) < j2) return false;
if(L[j2].get(i1 + 1, i2 - 1) > j1) return false;
return true;
}
ll count_rectangles(vector<vector<int>>a) {
short n = a.size();
short m = a[0].size();
for(int i = 0 ; i < n; i ++ ){
vector<short> mn;
for(int j = 0 ; j < m ; j ++ ){
lef[i][j]=-1;
while(!mn.empty() && a[i][mn.back()] < a[i][j]){
mn.pop_back();
}
if(!mn.empty())
lef[i][j] = mn.back();
mn.push_back(j);
}
mn.clear();
for(int j = m - 1; j >= 0 ; j -- ){
rig[i][j]=-1;
while(!mn.empty() && a[i][mn.back()] < a[i][j]){
mn.pop_back();
}
if(!mn.empty())
rig[i][j] = mn.back();
mn.push_back(j);
}
for(int j = 0 ; j < m ; j ++ ){
if(rig[i][j] != -1 && rig[i][j] > j + 1){
rr[i][j].push_back(mp(i, rig[i][j]));
}
if(lef[i][j] != -1 && lef[i][j] + 1 < j){
rr[i][lef[i][j]].push_back(mp(i,j));
}
}
}
for(int j = 0 ; j < m ; j ++ ){
vector<short> mn;
for(int i = 0 ; i < n; i ++ ){
up[i][j]=-1;
while(!mn.empty() && a[mn.back()][j] < a[i][j]){
mn.pop_back();
}
if(!mn.empty())
up[i][j] = mn.back();
mn.push_back(i);
}
mn.clear();
for(int i = n - 1; i >= 0 ; i -- ){
dow[i][j]=-1;
while(!mn.empty() && a[mn.back()][j] < a[i][j]){
mn.pop_back();
}
if(!mn.empty())
dow[i][j] = mn.back();
mn.push_back(i);
}
for(int i = 0 ; i < n; i ++ ){
if(dow[i][j] != -1 && i + 1 < dow[i][j]){
dd[i][j].push_back(mp(dow[i][j], j));
}
if(up[i][j] != -1 && up[i][j] + 1 < i){
dd[up[i][j]][j].push_back(mp(i, j));
}
}
}
for(int i = 0 ; i < m; i ++ ){
L[i].init(n,1);
R[i].init(n,0);
for(int j = 0 ; j < n; j ++ ){
R[i].upd(j,rig[j][i]);
L[i].upd(j,lef[j][i]);
}
}
for(int i = 0 ; i < n; i ++ ){
U[i].init(m,1);
D[i].init(m,0);
for(int j = 0 ; j < m ; j ++ ){
U[i].upd(j, up[i][j]);
D[i].upd(j, dow[i][j]);
sort(dd[i][j].begin(), dd[i][j].end());
dd[i][j].resize(unique(dd[i][j].begin(), dd[i][j].end()) - dd[i][j].begin());
sort(rr[i][j].begin(), rr[i][j].end());
rr[i][j].resize(unique(rr[i][j].begin(), rr[i][j].end()) - rr[i][j].begin());
}
}
int answ = 0;
for(int i = 1 ; i < n; i ++ ){
for(int j = 0 ; j + 1 < m ; j ++ ){
for(auto x : rr[i][j]){
for(auto y : dd[i - 1][j + 1]){
answ += is_valid(i - 1, j, y.fi, x.se);
}
}
}
}
return answ;
}
# | 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... |