Homochromatic square perimeters

December 3, 2021

Cells in an NN-by-NN grid GG are colored in monochrome:

 0i,j<N,let Gi,j={0white1black.\forall~0\leq i,j<N,\text{let}~G_{i,j}=\begin{cases} 0&\text{white}\\ 1&\text{black} \end{cases}.

Find the smallest non-negative integer KK, such that there exists no square of cells in GG, with side length K>KK'>K, whose perimeter consists entirely of black cells.

Codeforces/Polygon practice problem.

O(N3)O(N^3) via pre-computation

The problem reduces to finding the side length of the largest square whose perimeter is entirely black, or 00 if no black cells exist. We denote such squares valid. Let Li,jL_{i,j} store the largest length of consecutive black cells, starting from cell i,ji,j and moving left. For white cell Gi,j=0G_{i,j}=0, let Ri,j=0R_{i,j}=0. Similarly, define Ui,jU_{i,j} for moving upwards. The O(N2)O(N^2) indices for L,UL,U may be computed in O(1)O(1) each with the recurrence

Li,j={Gi,jj=00Gi,j=0Li,j1+1Gi,j=1L_{i,j}=\begin{cases} G_{i,j}&j=0\\ 0&G_{i,j}=0\\ L_{i,j-1}+1&G_{i,j}=1 \end{cases}

and similarly for UU.

Each square in GG may be specified by a tuple (i,j,k)(i,j,k) of upper-left corner i,ji,j and side length kk. The square Qi,j,kQ_{i,j,k} is valid if and only if all four edges are entirely black; that is, all four conditions below are satisfied:

{Li,j+k1ktop edgeUi+k1,j+k1kright edgeLi+k1,j+k1kbottom edgeUi+k1,jkleft edge\begin{cases} L_{i,j+k-1}\geq k&\text{top edge}\\ U_{i+k-1,j+k-1}\geq k&\text{right edge}\\ L_{i+k-1,j+k-1}\geq k&\text{bottom edge}\\ U_{i+k-1,j}\geq k&\text{left edge} \end{cases}

For each of the O(N3)O(N^3) squares, this check for validity costs O(1)O(1).

O(N3)O(N^3) C++ code.

O(N2α(N))O(N^2\alpha(N)) amortized via radix sort and DSU/Union-Find

First, compute L,UL',U', similarly to L,UL,U, but for lengths of black cells moving right, and downwards, respectively.

Each of the O(N)O(N) upper-left-to-bottom-right diagonals may be specified by (i,j)(i,j) as the diagonal which passes through cell i,ji,j. Denote the diagonals by DD. Note that Di,jD_{i,j} specifies the same diagonal as Di+1,j+1D_{i+1,j+1}.

For a given upper-left corner i,ji,j, we check all squares Qi,j,kQ_{i,j,k} for validity by querying a DSU for the maximum valid kk for that i,ji,j. To begin, define the reach RR over the diagonal:

Ri,j=min(Ui,j,Li,j)R_{i,j}=\min(U_{i,j},L_{i,j})

and reverse reach RR':

Ri,j=min(Ui,j,Li,j).R'_{i,j}=\min(U'_{i,j},L'_{i,j}).

Intuitively, the reach RR specifies the maximum side length for a valid square with bottom-right corner i,ji,j, while the reverse reach RR' specifies similarly for the upper-left corner i,ji,j. In other words, square Qi,j,kQ_{i,j,k} is valid if and only if both conditions below are satisfied:

{Ri,jkRi+k1,j+k1k.(1.1, 1.2)\begin{cases} R'_{i,j}\geq k\\ R_{i+k-1,j+k-1}\geq k \end{cases}.\tag{1.1, 1.2}

We can remove condition (1.2)(1.2)’s dependence on kk by defining the discounted reach RR'':

Ri,j=Ri,ji.R''_{i,j}=R_{i,j}-i.

(1.1,1.2)(1.1, 1.2) may now be rewritten:

{kRi,jRi+k1,j+k11i.(2.1, 2.2)\begin{cases} k\leq R'_{i,j}\\ R''_{i+k-1,j+k-1}\geq 1-i \end{cases}.\tag{2.1, 2.2}

We process the upper-left corners i,ji,j along diagonal Di,jD_{i,j} in increasing order of ii, 1i1-i decreases. Thus, the set SS of indices (i,j)=(i+k1,j+k1)(i',j')=(i+k-1,j+k-1) which satisfy (2.2)(2.2) never shrinks. More specifically, at i,ji,j, all bottom-right corners (i,j)(i',j') with Ri,j1iR''_{i',j'}\geq 1-i must be added to SS. As we have already processed (i1,j1)(i-1,j-1) at this point, only the bottom-right corners which satisfy Ri,j=1i+1R''_{i',j'}=1-i+1 need to be added. We may query for these (i,j)(i',j') in O(1)O(1) by pre-sorting in O(N)O(N), with radix sort, all the Ri,jR''_{i',j'} on the diagonal.

At a given upper-left corner i,ji,j, then, the maximal valid bottom-right corner is the maximal (i,j)S(i',j')\in S which also satisfies (2.1)(2.1):

k=ii+1Ri,j    iRi,j+i1.(3)k=i'-i+1\leq R'_{i,j}\implies i'\leq R'_{i,j}+i-1.\tag{3}

Formally, we wish to make two types of queries to set SS:

  1. Add(i,j)Add(i,j): Add (i,j)(i,j) to the set.
  2. Get(i)Get(i'): Query the largest (i,j)(i,j) in the set with iii\leq i'.

Observe that for some i,ji,j, if (i,j)S(i,j)\notin S, then Get(i)=Get(i1)Get(i)=Get(i-1). This leads us to consider implementing SS with a DSU. Should we process upper-left corners in decreasing order of ii instead of increasing order, 1i1-i increases, and SS).

Intuitively, the reach RR specifies the maximum side length for a valid square with bottom-right corner i,ji,j, while the reverse reach RR' specifies similarly for the upper-left corner i,ji,j. In other words, square Qi,j,kQ_{i,j,k} is valid if and only if both conditions below are satisfied:

{Ri,jkRi+k1,j+k1k.(1.1, 1.2)\begin{cases} R'_{i,j}\geq k\\ R_{i+k-1,j+k-1}\geq k \end{cases}.\tag{1.1, 1.2}

We can remove condition (1.2)(1.2)’s dependence on kk by defining the discounted reach RR'':

Ri,j=Ri,ji.R''_{i,j}=R_{i,j}-i.

(1.1,1.2)(1.1, 1.2) may now be rewritten:

{kRi,jRi+k1,j+k11i.(2.1, 2.2)\begin{cases} k\leq R'_{i,j}\\ R''_{i+k-1,j+k-1}\geq 1-i \end{cases}.\tag{2.1, 2.2}

We process the upper-left corners i,ji,j along diagonal Di,jD_{i,j} in increasing order of ii, 1i1-i decreases. Thus, the set SS of indices (i,j)=(i+k1,j+k1)(i',j')=(i+k-1,j+k-1) which satisfy (2.2)(2.2) never shrinks. More specifically, at i,ji,j, all bottom-right corners (i,j)(i',j') with Ri,j1iR''_{i',j'}\geq 1-i must be added to SS. As we have already processed (i1,j1)(i-1,j-1) at this point, only the bottom-right corners which satisfy Ri,j=1i+1R''_{i',j'}=1-i+1 need to be added. We may query for these (i,j)(i',j') in O(1)O(1) by pre-sorting in O(N)O(N), with radix sort, all the Ri,jR''_{i',j'} on the diagonal.

At a given upper-left corner i,ji,j, then, the maximal valid bottom-right corner is the maximal (i,j)S(i',j')\in S which also satisfies (2.1)(2.1):

k=ii+1Ri,j    iRi,j+i1.(3)k=i'-i+1\leq R'_{i,j}\implies i'\leq R'_{i,j}+i-1.\tag{3}

Formally, we wish to make two types of queries to set SS:

  1. Add(i,j)Add(i,j): Add (i,j)(i,j) to the set.
  2. Get(i)Get(i'): Query the largest (i,j)(i,j) in the set with iii\leq i'.

Observe that for some i,ji,j, if (i,j)S(i,j)\notin S, then Get(i)=Get(i1)Get(i)=Get(i-1). This leads us to consider implementing SS with a DSU. Should we process upper-left corners in decreasing order of ii instead of increasing order, 1i1-i increases, and SS never grows. Thus, instead of AddAdd, we wish to support RemoveRemove.

Before moving on to the reduction to DSU, we first discuss an example.

Take, for example, the following input GG with K=4K=4 from the square with upper-left corner at (1,1)(1, 1):

110111
011110
010011
111011
111111
111111

Consider the processing of the major diagonal D0,0D_{0, 0}. As mentioned, we step through the diagonal in decreasing order of ii.

ii jj RR RR' RR'' R+i1R'+i-1 1i1-i
55 55 44 11 1-1 55 4-4
44 44 55 22 11 55 3-3
33 33 00 00 3-3 22 2-2
22 22 00 00 2-2 11 1-1
11 11 11 44 00 44 00
00 00 11 11 11 00 11

Observe, as noted previously, that R+i1R'+i-1 intuitively calculates the maximum row index which may serve as a bottom-right corner for a given upper-left corner i,ji,j. In addition, for any upper-left corner i,ji,j, it may form a valid square with bottom-right corner i,ji',j' as long as Ri,j1iR''_{i',j'}\geq 1-i and Ri,j+i1iR'_{i,j}+i-1\geq i'. These together describe conditions (2.2)(2.2) and (3)(3), respectively.

To visualize the operations on SS, we arrange it onto a line with corner (0,0)(0,0) on the left and (5,5)(5,5) on the right. Initially, all corners are part of SS:

||||||
012345

At any point in time, we either remove an element from SS, or we stand at some point on the line, and look left to identify the index of the first | blocking our view. Since SS is unchanged prior to visiting (3,3)(3,3), we take that as our first example. As 1i1-i is 2-2, we must remove all (i,j)(i',j') from SS where Ri,jR''_{i',j'} is smaller than 2-2. Thus, we remove (3,3)(3,3) from SS:

|||_||
012345

Intuitively, (3,3)(3,3) has been removed from consideration as a bottom-right corner. This is because any bottom or right edges which extend from it can no longer reach any upper-left corners we have yet to process, or the upper-left corner we are currently processing: (3,3)(3,3).

We wrap up processing upper-left corner (3,3)(3,3) by querying SS for the maximal bottom-right corner with iR3,3+31=2i'\leq R'_{3,3}+3-1=2, which is the bottom-right corner (2,2)(2,2). To visualize this, imagine standing at index 22 on the SS line and looking left for the first | blocking your vision (index 22 counts). This is the