#include<iostream>
#include<vector>
#include<algorithm>
#include<tuple>
#include<queue>
#include<set>
#include "soccer.h"
using namespace std;
const int MAX_N=2e3+3;
int n;
int a[MAX_N][MAX_N];
int p[MAX_N][MAX_N];
int lastok[2][MAX_N][MAX_N];//0 : back | 1 : forward
set<int>block[MAX_N];
bool allempty(int x1,int y1,int x2,int y2)
{
int x11=min(x1,x2),x22=max(x1,x2);
int y11=min(y1,y2),y22=max(y1,y2);
x1=x11+1;y1=y11+1;x2=x22+1;y2=y22+1;
if(p[x2][y2]-p[x1-1][y2]-p[x2][y1-1]+p[x1-1][y1-1]==(x2-x1+1)*(y2-y1+1))return 1;
return 0;
}
int tree[2][2][MAX_N][4*MAX_N];
int lazy[2][2][MAX_N][4*MAX_N];
void push_lazy(int topbottom,int dir,int node,int l,int r,int row)
{
tree[topbottom][dir][row][node]=max(tree[topbottom][dir][row][node],lazy[topbottom][dir][row][node]);
if(l!=r)
{
lazy[topbottom][dir][row][2*node]=max(lazy[topbottom][dir][row][2*node],lazy[topbottom][dir][row][node]);
lazy[topbottom][dir][row][2*node+1]=max(lazy[topbottom][dir][row][2*node+1],lazy[topbottom][dir][row][node]);
}
lazy[topbottom][dir][row][node]=0;
}
void update(int topbottom,int dir,int node,int l,int r,int row,int ql,int qr,int val)
{
push_lazy(topbottom,dir,node,l,r,row);
if(r<ql or l>qr)return;
if(ql<=l && r<=qr)
{
lazy[topbottom][dir][row][node]=max(lazy[topbottom][dir][row][node],val);
push_lazy(topbottom,dir,node,l,r,row);
return;
}
int mid=(l+r)/2;
update(topbottom,dir,2*node,l,mid,row,ql,qr,val);
update(topbottom,dir,2*node+1,mid+1,r,row,ql,qr,val);
tree[topbottom][dir][row][node]=max(tree[topbottom][dir][row][2*node],tree[topbottom][dir][row][2*node+1]);
}
int query(int topbottom,int dir,int node,int l,int r,int row,int idx)
{
push_lazy(topbottom,dir,node,l,r,row);
if(r<idx or l>idx)return -1;
if(l==r)
{
return tree[topbottom][dir][row][node];
}
int mid=(l+r)/2;
return max(query(topbottom,dir,2*node,l,mid,row,idx),query(topbottom,dir,2*node+1,mid+1,r,row,idx));
}
void rowupdate(int topbottom,int row,int leftborder,int rightborder,int cur)
{
auto it=block[row].lower_bound(leftborder);
int first=(*(it));
if(first>rightborder+1)return;
auto it2=block[row].upper_bound(rightborder);
int last=(*(it2));
if(last>rightborder+1)
{
it2--;
}
last=(*(it2));
if(leftborder<=last-1)update(topbottom,1,1,0,n-1,row,leftborder,last-1,cur);
if(first+1<=rightborder)update(topbottom,0,1,0,n-1,row,first+1,rightborder,cur);
}
vector<tuple<int,int,bool>>states[MAX_N];
int solve()
{
int ans=1;
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
if(a[i][j])continue;
int l=j,r=lastok[1][i][j];
states[r-l+1].push_back({i,j,1});
l=lastok[0][i][j];r=j;
states[r-l+1].push_back({i,j,0});
}
}
for(int len=1;len<=n;len++)sort(states[len].rbegin(),states[len].rend());
for(int len=n;len>=1;len--)
{
for(auto [row,col,dir]:states[len])
{
int leftborder=min(col,lastok[dir][row][col]),rightborder=max(col,lastok[dir][row][col]);
int l=row,r=n-1;
int row2;
while(l<=r)
{
int mid=(l+r)/2;
if(allempty(row,leftborder,mid,rightborder))
{
row2=mid;
l=mid+1;
}
else r=mid-1;
}
int cur=len+query(0,dir,1,0,n-1,row,col);
ans=max(ans,cur);
/*if(row-1>=0)
{
l=0;r=row;
int row3;
while(l<=r)
{
int mid=(l+r)/2;
if(allempty(mid,leftborder,row,rightborder))
{
row3=mid;
r=mid-1;
}
else l=mid+1;
}
cur+=(row-row3)*len;
if(row3>0)rowupdate(0,row3-1,leftborder,rightborder,cur);
ans=max(ans,cur);
}*/
for(int row3=row-1;row3>=0;row3--)
{
if(allempty(row3,leftborder,row3,rightborder))
{
if(block[row3].count(leftborder-1) && block[row3].count(rightborder+1))
{
rowupdate(0,row3,leftborder,rightborder,cur);
break;
}
}
else
{
rowupdate(0,row3,leftborder,rightborder,cur);
break;
}
cur+=len;
}
if(row2+1<n)rowupdate(1,row2+1,leftborder,rightborder,cur);
}
///minimum at the top
reverse(states[len].begin(),states[len].end());
for(auto [row,col,dir]:states[len])
{
int leftborder=min(col,lastok[dir][row][col]),rightborder=max(col,lastok[dir][row][col]);
int l=0,r=row;
int row2;
while(l<=r)
{
int mid=(l+r)/2;
if(allempty(mid,leftborder,row,rightborder))
{
row2=mid;
r=mid-1;
}
else l=mid+1;
}
int cur=len+query(1,dir,1,0,n-1,row,col);
ans=max(ans,cur);
/*if(row+1<n)
{
l=row;r=n-1;
int row3;
while(l<=r)
{
int mid=(l+r)/2;
if(allempty(row,leftborder,mid,rightborder))
{
row3=mid;
l=mid+1;
}
else r=mid-1;
}
cur+=(row3-row)*len;
if(row3+1<n)rowupdate(1,row3+1,leftborder,rightborder,cur);
ans=max(ans,cur);
}*/
for(int row3=row+1;row3<n;row3++)
{
if(allempty(row3,leftborder,row3,rightborder))
{
if(block[row3].count(leftborder-1) && block[row3].count(rightborder+1))
{
rowupdate(1,row3,leftborder,rightborder,cur);
break;
}
}
else
{
rowupdate(1,row3,leftborder,rightborder,cur);
break;
}
cur+=len;
}
if(row2-1>=0)rowupdate(0,row2-1,leftborder,rightborder,cur);
}
///minimum at the bottom
}
return ans;
}
int biggest_stadium(int N, std::vector<std::vector<int>> F)
{
n=N;
for(int i=0;i<n;i++)
{
block[i].insert(-1);
block[i].insert(n);
for(int j=0;j<n;j++)
{
a[i][j]=F[i][j];
if(a[i][j])block[i].insert(j);
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
p[i][j]=(a[i-1][j-1]==0)+p[i-1][j]+p[i][j-1]-p[i-1][j-1];
}
}
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
if(a[i][j])continue;
if(j==0 or a[i][j-1])
{
lastok[0][i][j]=j;
continue;
}
lastok[0][i][j]=lastok[0][i][j-1];
}
for(int j=n-1;j>=0;j--)
{
if(a[i][j])continue;
if(j==n-1 or a[i][j+1])
{
lastok[1][i][j]=j;
continue;
}
lastok[1][i][j]=lastok[1][i][j+1];
}
}
return solve();
}
| # | 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... |