# | Time | Username | Problem | Language | Result | Execution time | Memory |
---|---|---|---|---|---|---|---|
226450 | tinjyu | Rectangles (IOI19_rect) | C++14 | 0 ms | 0 KiB |
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 "rect.h"
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
struct node{
long long int x, y;
}array[7000000];
long long int u[2505][2505],d[2505][2505],n,m,s[2505][2505][13][2],l[2505][2505],st2[2505][2505][13][2],r[2505][2505],t[10005][2],bits[20];
long long int find(int i,int j)
{
//cout<<i<<" "<<j<<endl;
long long int x1=l[i][j],y1=u[i][j],x2=r[i][j],y2=d[i][j];
long long int le=l[i][j]+1,ri=r[i][j]-1;
long long int k=log2(ri-le+1);
//cout<<y1<<" "<<x1<<" "<<y2<<" "<<x2<<" "<<le<<" "<<ri<<endl;
//cout<<s[y1][le][k][1]<<" "<<s[y1][ri-bits[k]+1][k][1]<<endl;
if( min ( s[y1][le][k][1] , s[y1][ri-bits[k]+1][k][1] ) < y2 ) return 0;
//cout<<s[y2][le][k][0]<<" "<<s[y2][ri-bits[k]+1][k][0]<<endl;
if( max ( s[y2][le][k][0] , s[y2][ri-bits[k]+1][k][0] ) > y1 ) return 0;
long long int up=u[i][j]+1,down=d[i][j]-1;
//cout<<up<<" "<<down<<endl;
k=log2(down-up+1);
//cout<<st2[up][x1][k][1]<<" "<<st2[down-bits[k]+1][x1][k][1]<<endl;
if( min ( st2[up][x1][k][1] , st2[down-bits[k]+1][x1][k][1] ) < x2) return 0;
//cout<<st2[up][x2][k][0]<<" "<<st2[down-bits[k]+1][x2][k][0]<<endl;
if( max ( st2[up][x2][k][0] , st2[down-bits[k]+1][x2][k][0] ) > x1 )return 0;
return 1;
}
bool cmp(node ax,node ay)
{
long long int ar[10][4];
ar[0][0]=u[ax.x][ax.y];
ar[0][1]=l[ax.x][ax.y];
ar[0][2]=d[ax.x][ax.y];
ar[0][3]=r[ax.x][ax.y];
ar[1][0]=u[ay.x][ay.y];
ar[1][1]=l[ay.x][ay.y];
ar[1][2]=d[ay.x][ay.y];
ar[1][3]=r[ay.x][ay.y];
for(int i=0;i<4;i++)
{
if(ar[0][i]<ar[1][i])return 1;
if(ar[0][i]>ar[1][i])return 0;
}
return 0;
}
long long count_rectangles(std::vector<std::vector<int> > a) {
n=a.size();
m=a[0].size();
for(int i=0;i<n;i++)
{
long long int p=0,st=0,en=-1;
for(int j=0;j<m;j++)
{
l[i][j]=-1;
r[i][j]=5000;
for(int k=en;k>=st;k--)
{
if(a[i][j]>t[k][0])
{
r[i][t[k][1]]=j;
en--;
}
else
{
en++;
t[en][0]=a[i][j];
t[en][1]=j;
if(a[i][j]<t[k][0])l[i][j]=t[k][1];
else l[i][j]=l[i][t[k][1]];
break;
}
}
if(en==-1)
{
en=0;
t[en][0]=a[i][j];
t[en][1]=j;
}
}
}
for(int j=0;j<m;j++)
{
long long int p=0,st=0,en=-1;
for(int i=0;i<n;i++)
{
u[i][j]=-1;
d[i][j]=5000;
for(int k=en;k>=st;k--)
{
if(a[i][j]>t[k][0])
{
d[t[k][1]][j]=i;
en--;
}
else
{
en++;
t[en][0]=a[i][j];
t[en][1]=i;
if(a[i][j]<t[k][0])u[i][j]=t[k][1];
else u[i][j]=u[t[k][1]][j];
break;
}
}
if(en==-1)
{
en=0;
t[en][0]=a[i][j];
t[en][1]=i;
}
}
}
for(int i=0;i<n;i++)
{
long long int p=0,st=0,en=-1;
for(int j=0;j<m;j++)
{
st2[i][j][0][0]=-1;
st2[i][j][0][1]=5000;
for(int k=en;k>=st;k--)
{
if(a[i][j]>=t[k][0])
{
st2[i][t[k][1]][0][1]=j;
en--;
if(a[i][j]==t[k][0])
{
st2[i][j][0][0]=t[k][1];
en++;
t[en][0]=a[i][j];
t[en][1]=j;
break;
}
}
else
{
en++;
t[en][0]=a[i][j];
t[en][1]=j;
st2[i][j][0][0]=t[k][1];
break;
}
}
if(en==-1)
{
en=0;
t[en][0]=a[i][j];
t[en][1]=j;
}
}
}
for(int j=0;j<m;j++)
{
long long int p=0,st=0,en=-1;
for(int i=0;i<n;i++)
{
s[i][j][0][0]=-1;
s[i][j][0][1]=5000;
for(int k=en;k>=st;k--)
{
if(a[i][j]>=t[k][0])
{
s[t[k][1]][j][0][1]=i;
en--;
if(a[i][j]==t[k][0])
{
s[i][j][0][0]=t[k][1];
en++;
t[en][0]=a[i][j];
t[en][1]=i;
break;
}
}
else
{
en++;
t[en][0]=a[i][j];
t[en][1]=i;
s[i][j][0][0]=t[k][1];
break;
}
}
if(en==-1)
{
en=0;
t[en][0]=a[i][j];
t[en][1]=i;
}
}
}
//cout<<st2[4][16][0][1]<<endl;
bits[0]=1;
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
//cout<<i<<" "<<j<<" "<<st2[i][j][0][0]<<" "<<st2[i][j][0][1]<<" "<<l[i][j]<<" "<<r[i][j]<<" "<<s[i][j][0][0]<<" "<<s[i][j][0][1]<<" "<<u[i][j]<<" "<<d[i][j]<<endl;
}
}
for(int i=1;i<=15;i++)bits[i]=bits[i-1]*2;
for(int k=1;bits[k-1]<=m;k++)
{
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
if(j+bits[k-1]>=m)break;
s[i][j][k][0]=max(s[i][j][k-1][0],s[i][j+bits[k-1]][k-1][0]);
s[i][j][k][1]=min(s[i][j][k-1][1],s[i][j+bits[k-1]][k-1][1]);
//cout<<i<<" "<<j<<" "<<k<<" "<<st2[i][j][k][0]<<" "<<st2[i][j][k][1]<<endl;
}
}
}
for(int k=1;bits[k-1]<=n;k++)
{
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
if(i+bits[k-1]>=n)break;
st2[i][j][k][0]=max(st2[i][j][k-1][0],st2[i+bits[k-1]][j][k-1][0]);
st2[i][j][k][1]=min(st2[i][j][k-1][1],st2[i+bits[k-1]][j][k-1][1]);
//if(j==6)cout<<i<<" "<<j<<" "<<k<<" "<<st2[i][j][k][0]<<" "<<st2[i][j][k][1]<<endl;
}
}
}
long long int ans=0;
long long int cnt=0;
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
if(u[i][j]==-1 || d[i][j]==5000 || l[i][j]==-1 || r[i][j]==5000)continue;
//if((a[i-1][j]==a[i][j] && i!=1) || (a[i][j-1]==a[i][j] && j!=1))continue;
cnt++;
array[cnt].x=i;
array[cnt].y=j;
}
}
sort(array+1,array+cnt+1,cmp);
//cout<<cnt<<endl;
for(int i=1;i<=cnt;i++)
{
long long int x=array[i].x,y=array[i].y,x1=array[i-1].x,y1=array[i-1].y;
if(u[x][y]==u[x1][y1] && d[x][y]==d[x1][y1] && l[x][y]==l[x1][y1] && r[x][y]==r[x1][y1])continue;
long long int tmp=find(x,y);
if(tmp==1)
//cout<<s[x][y][0][0]+1<<" "<<st2[x][y][0][0]+1<<" "<<s[x][y][0][1]-1<<" "<<st2[x][y][0][1]-1<<endl;
//cout<<endl;
ans+=tmp;
}
return ans;
}