#include "rect.h"
#include <bits/stdc++.h>
#define ll long long
#define ld long double
#define vi vector<int>
#define vl vector<long long>
#define ff first
#define ss second
#define pii pair<int,int>
#define pll pair<long long, long long>
#define pb push_back
#define rep(i, b) for(int i = 0; i < (b); ++i)
#define rep2(i,a,b) for(int i = a; i <= (b); ++i)
#define rep3(i,a,b,c) for(int i = a; i <= (b); i+=c)
#define count_bits(x) __builtin_popcountll((x))
#define all(x) (x).begin(),(x).end()
#define siz(x) (int)(x).size()
#define forall(it,x) for(auto& it:(x))
using namespace std;
const int INF = 1e9+50;
const ll INF_L = 1e18+40;
const ll MOD = 1e9+7;
const int tree_siz = 1024*8-1;
int sum[tree_siz+1];
int get_sum(int akt, int p1, int p2, int s1, int s2)
{
if(p2 < s1 || p1 > s2) return 0;
if(p1 >= s1 && p2 <= s2) return sum[akt];
return get_sum(akt*2,p1,(p1+p2)/2,s1,s2)+get_sum(akt*2+1,(p1+p2)/2+1,p2,s1,s2);
}
void upd(int v)
{
sum[v] = sum[v*2]+sum[v*2+1];
if(v != 1) upd(v/2);
}
void change(int ind, int x)
{
sum[tree_siz/2+ind+1] += x;
upd((tree_siz/2+1+ind)/2);
}
vector<pair<short,short>> X_segs[2501][2501];
vector<pair<short,short>> Y_segs[2501][2501];
vector<pair<short,short>> count_regions(vi& x)
{
vector<pair<short,short>> ans;
stack<int> st;
rep(i,siz(x))
{
while(!st.empty() && x[st.top()] < x[i]) st.pop();
if(i != 0 && siz(st) != 0)
{
int end_ = st.top()+1;
if(end_ <= i-1)
{
ans.pb({end_,i-1});
}
}
st.push(i);
}
while(!st.empty()) st.pop();
for(int i = siz(x)-1; i >= 0; i--)
{
while(!st.empty() && x[st.top()] < x[i]) st.pop();
if(i != siz(x)-1 && siz(st) != 0)
{
int end_ = st.top()-1;
if(end_ >= i+1)
{
ans.pb({i+1,end_});
}
}
st.push(i);
}
sort(all(ans));
vector<pair<short,short>> ans2;
pii pop = {-1,-1};
forall(it,ans)
{
if(it.ff == pop.ff && it.ss == pop.ss) continue;
ans2.pb(it);
pop = it;
}
return ans2;
}
int first_poz[2501][2501];
int last_poz[2501][2501];
ll count_rectangles(vector<vi> arr)
{
int n = siz(arr);
int m = siz(arr[0]);
vector<pair<short,short>> segs;
for(int i = n-2; i >= 1; i--)
{
segs = count_regions(arr[i]);
forall(it,segs)
{
int last_iter = i;
if(first_poz[it.ff][it.ss] == i+1) last_iter = last_poz[it.ff][it.ss];
else
{
last_poz[it.ff][it.ss] = i;
}
first_poz[it.ff][it.ss] = i;
Y_segs[i][it.ff].pb({last_iter,it.ss});
}
}
rep(i,2501) rep(j,2501)
{
last_poz[i][j] = 0;
first_poz[i][j] = 0;
}
vi arr2(n);
for(int j = m-2; j >= 1; j--)
{
rep(i,n) arr2[i] = arr[i][j];
segs = count_regions(arr2);
forall(it,segs)
{
int last_iter = j;
if(first_poz[it.ff][it.ss] == j+1) last_iter = last_poz[it.ff][it.ss];
else
{
last_poz[it.ff][it.ss] = j;
}
first_poz[it.ff][it.ss] = j;
X_segs[it.ff][j].pb({it.ss,last_iter});
}
}
ll ans = 0;
rep2(i,1,n-2)
{
rep2(j,1,m-2)
{
sort(all(X_segs[i][j]));
sort(all(Y_segs[i][j]));
reverse(all(Y_segs[i][j]));
int cur_Y = siz(Y_segs[i][j])-1;
forall(it,Y_segs[i][j])
{
change(it.ss,1);
}
forall(it,X_segs[i][j])
{
while(cur_Y >= 0 && Y_segs[i][j][cur_Y].ff < it.ff)
{
change(Y_segs[i][j][cur_Y].ss,-1);
cur_Y--;
}
ans += get_sum(1,0,tree_siz/2,0,it.ss);
}
rep(k,cur_Y+1)
{
change(Y_segs[i][j][k].ss,-1);
}
}
}
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... |