이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#pragma GCC optimize ("O3")
#pragma GCC optimize ("Ofast")
#pragma GCC optimize ("unroll-loops")
#include <bits/stdc++.h>
#include "rect.h"
#define ll long long
#define pb push_back
#define x first
#define y second
using namespace std;
vector<vector<set<pair<int,int>>>> mp,mp2;
vector<int> bit(2501);
void upd(int x, int val)
{
x++;
for(;x<=2500;x+=(x&-x))
bit[x]+=val;
}
int getpre(int x)
{
x++;
int ret=0;
for(;x>0;x-=(x&-x))
ret+=bit[x];
return ret;
}
ll count_rectangles(vector<vector<int>> a)
{
int n=a.size(), m=a[0].size();
for(int i=0;i<n;i++)
mp.pb(vector<set<pair<int,int>>>(m)), mp2.pb(vector<set<pair<int,int>>>(m));
for(int i=1;i<n-1;i++)
{
fill(bit.begin(),bit.end(),0);
vector<pair<int,int>> vp;
for(int j=0;j<m;j++) vp.pb({a[i][j],j});
sort(vp.begin(),vp.end());
for(int j=0;j<m;j++)
{
upd(vp[j].y,1);
int l=vp[j].y, r=m-1;
while(l<r)
{
int md=(l+r)/2+1;
if(getpre(md)-getpre(vp[j].y)==md-vp[j].y) l=md;
else r=md-1;
}
int l2=0, r2=vp[j].y;
while(l2<r2)
{
int md=(l2+r2)/2;
if(getpre(vp[j].y)-getpre(md-1)==vp[j].y-md+1) r2=md;
else l2=md+1;
}
if(l2==0 || l==m-1) continue;
if(a[i][l+1]==vp[j].x || a[i][l2-1]==vp[j].x) continue;
int num=1;
if(int(mp[i-1][l2-1].size()))
{
auto it = mp[i-1][l2-1].lower_bound({l+1,0});
if(it!=mp[i-1][l2-1].end()) if((*it).x==l+1) num+=(*it).y;
}
mp[i][l2-1].insert({l+1,num});
num=1;
if((int)mp[i-1][l+1].size())
{
auto it = mp[i-1][l+1].lower_bound({l2-1,0});
if(it!=mp[i-1][l+1].end()) if((*it).x==l2-1) num+=(*it).y;
}
mp[i][l+1].insert({l2-1,num});
}
}
ll ans=0;
for(int i=1;i<m-1;i++)
{
fill(bit.begin(),bit.end(),0);
vector<pair<int,int>> vp;
for(int j=0;j<n;j++) vp.pb({a[j][i],j});
sort(vp.begin(),vp.end());
for(int j=0;j<n;j++)
{
upd(vp[j].y,1);
int l=vp[j].y, r=n-1;
while(l<r)
{
int md=(l+r)/2+1;
if(getpre(md)-getpre(vp[j].y)==md-vp[j].y) l=md;
else r=md-1;
}
int l2=0, r2=vp[j].y;
while(l2<r2)
{
int md=(l2+r2)/2;
if(getpre(vp[j].y)-getpre(md-1)==vp[j].y-md+1) r2=md;
else l2=md+1;
}
if(l2==0 || l==n-1) continue;
if(a[l+1][i]==vp[j].x || a[l2-1][i]==vp[j].x) continue;
int num=1;
if((int)mp2[l2-1][i-1].size())
{
auto it = mp2[l2-1][i-1].lower_bound({l+1,0});
if(it!=mp2[l2-1][i-1].end()) if((*it).x==l+1) num+=(*it).y;
}
mp2[l2-1][i].insert({l+1,num});
num=1;
if((int)mp2[l+1][i-1].size())
{
auto it = mp2[l+1][i-1].lower_bound({l2-1,0});
if(it!=mp2[l+1][i-1].end()) if((*it).x==l2-1) num+=(*it).y;
}
mp2[l+1][i].insert({l2-1,num});
auto it = mp[l][i+1].lower_bound({i-num,l-l2+1});
for(;it!=mp[l][i+1].end();it++)
{
if((*it).x>i+1) break;
if((*it).y>=l-l2+1) ans++;
}
}
}
return ans;
}
/*int main()
{
freopen("test.in","r",stdin)
int n,m; cin>>n>>m;
vector<vector<int>> a(n);
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
{
int k; cin>>k;
a[i].pb(k);
}
cout<<count_rectangles(a);
}*/
# | 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... |