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"
//#include "grader.cpp"
using namespace std ;
const int MAX = 2501 ;
vector<int>bit[MAX][MAX] ;
vector<int>v2[MAX][MAX] ;
int getidx(int i , int j , int x)
{
int idx = upper_bound(v2[i][j].begin() , v2[i][j].end() , x) - v2[i][j].begin() ;
return idx ;
}
void Add(int i2 , int j2 , int i , int x)
{
int n = v2[i2][j2].size() ;
for(; i <= n ; i += (i & (-i)))
bit[i2][j2][i] += x ;
}
void Insert(int i2 , int j2 , int i)
{
Add(i2 , j2 , getidx(i2 , j2 , i) , 1) ;
}
void Erase(int i2 , int j2 , int i)
{
Add(i2 , j2 , getidx(i2 , j2 , i) , -1) ;
}
int get(int i2 , int j2 , int i)
{
int sum = 0 ;
for(; i > 0 ; i -= (i & (-i)))
sum += bit[i2][j2][i] ;
return sum ;
}
int query(int i2 , int j2 , int i)
{
return get(i2 , j2 , getidx(i2 , j2 , i)) ;
}
void init(int i , int j)
{
int n = v2[i][j].size() ;
bit[i][j] = vector<int>(n+1 , 0) ;
for(auto &x : v2[i][j])
Insert(i , j , x) ;
}
vector<int>candi[MAX] ;
stack<int>st[MAX] ;
vector<bool>mark[MAX] ;
int n , m ;
int calc(int i , int j , int i2 , int last)
{
int j2 = j-1 ;
i2++ ;
if(j2 < 0 || i2 >= i)
return 0ll ;
return (query(i2 , j2 , last+1) - query(i2 , j2 , j)) ;
}
vector< vector<int> >a ;
vector<int>erased ;
stack<int>st2 ;
void AddRow(int i)
{
while(st2.size())
st2.pop() ;
for(int j = m-1 ; j >= 0 ; --j)
{
while(st2.size() && a[i][j] > a[i][st2.top()])
v2[i][j].push_back(st2.top()) , st2.pop() ;
if(st2.size())
v2[i][j].push_back(st2.top()) ;
while(st2.size() && a[i][st2.top()] == a[i][j])
st2.pop() ;
st2.push(j) ;
sort(v2[i][j].begin() , v2[i][j].end()) ;
init(i , j) ;
}
if(!i)
return ;
for(int j = 0 ; j < m ; ++j)
{
erased.clear() ;
for(auto &k : v2[i-1][j])
{
if(!binary_search(v2[i][j].begin() , v2[i][j].end() , k))
erased.push_back(k) ;
}
for(auto &k : erased)
{
for(int i2 = i-1 ; i2 >= 0 ; --i2)
{
if(!binary_search(v2[i2][j].begin() , v2[i2][j].end() , k))
break ;
Erase(i2 , j , k) ;
}
}
}
}
long long count_rectangles(std::vector<std::vector<int> > v)
{
a = v ;
n = a.size() , m = a[0].size() ;
long long ans = 0 ;
for(int i = 0 ; i < n ; ++i)
{
for(int j = 0 ; j < m ; ++j)
{
while(st[j].size() && a[i][j] > a[st[j].top()][j])
candi[j].push_back(st[j].top()) , st[j].pop() ;
if(st[j].size())
candi[j].push_back(st[j].top()) ;
while(st[j].size() && a[st[j].top()][j] == a[i][j])
st[j].pop() ;
st[j].push(i) ;
sort(candi[j].begin() , candi[j].end()) ;
mark[j] = vector<bool>(candi[j].size() , 0) ;
}
for(int j = 0 ; j < m ; ++j)
{
for(auto &i2 : candi[j])
{
int idx = lower_bound(candi[j].begin() , candi[j].end() , i2) - candi[j].begin() ;
if(mark[j][idx])
continue ;
int last = j ;
for(int k = j ; k < m ; ++k)
{
if(!binary_search(candi[k].begin() , candi[k].end() , i2))
break ;
last = k ;
}
for(int k = j ; k <= last ; ++k)
{
ans += calc(i , k , i2 , last) ;
if(k != j)
{
idx = lower_bound(candi[k].begin() , candi[k].end() , i2) - candi[k].begin() ;
mark[k][idx] = 1 ;
}
}
}
candi[j].clear() , mark[j].clear() ;
}
AddRow(i) ;
}
return ans ;
}
# | 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... |