APIO 2011 - Table Coloring

Author: Andi Qu

Explanation

TL;DR

If we view the grid as a graph, we get KK connected components. The answer is then either 2K12^{K - 1} or 00 and we use DSU or DFS to determine which one it is.

Intuition

Let c(x,y)=1c(x, y) = 1 if the cell (x,y)(x, y) is blue and 00 otherwise. For convenience, also add a row 0 and column 0.

Firstly, notice that if we already know the color of 3 cells in a 2×22 \times 2 table, then we also know the last color.

From this, we get the recurrence

c(x,y)=¬(c(x1,y1)c(x1,y)c(x,y1))c(x, y) = \lnot (c(x - 1, y - 1) \oplus c(x - 1, y) \oplus c(x, y - 1))

for all x,y>1x, y > 1.

After analysing this recurrence, we find that we actually have

c(x,y)=(c(0,0)c(0,y)c(x,0)((xy)%2))c(x, y) = (c(0, 0) \oplus c(0, y) \oplus c(x, 0) \oplus ((x \cdot y) \% 2))

I made a helpful spreadsheet for you to visualise this.

Counting the colorings

Without loss of generality, let the cell (0,0)(0, 0) be red (since its color doesn't change the answer). This means that without any already-colored cells, all cells (x,0)(x, 0) and (0,y)(0, y) are independent.

However, an already-colored cell (x,y)(x, y) makes the 2 cells (x,0)(x, 0) and (0,y)(0, y) depend on each other.

View the grid as a graph:

  • All cells (x,0)(x, 0) and (0,y)(0, y) are nodes.
  • For each already-colored cell (x,y)(x, y), add an edge between (x,0)(x, 0) and (0,y)(0, y) with weight c(x,0)c(0,y)c(x, 0) \oplus c(0, y).

This creates KK connected components. The answer is thus either 2K12^{K - 1} or 00. This is because each node in a connected component is dependent on the other nodes in that component and all connected components are independent. If it simply isn't possible to color the table, the answer is 00.

Checking Whether the Answer is 00

This problem then becomes checking whether there is an cycle with odd weight in the resulting graph, which we can answer efficiently using DSU or DFS.

One way to implement this is as follows. Since each already-colored cell (x,y)(x, y) determines whether the colors of the cells (x,0)(x, 0) and (0,y)(0, y) are the same, we can instead split each node in our graph into 2 nodes (one for each color) and create edges between nodes with consistent colors. The answer is 00 if two new nodes corresponding to the same original node are in the same connected component.

Implementation

Time Complexity: O((N+M+K)log(N+M+K))\mathcal{O}((N+M+K)\log (N+M+K))

C++

#include <bits/stdc++.h>
#define FOR(i, x, y) for (int i = x; i < y; i++)
using namespace std;
const int MOD = 1e9;
int x[100001], y[100001], cmp[400001];
int find(int A) {
while (A != cmp[A]) cmp[A] = cmp[cmp[A]], A = cmp[A];

Join the USACO Forum!

Stuck on a problem, or don't understand a module? Join the USACO Forum and get help from other competitive programmers!