← All problems

AI Finds Nothing Here

Codeforces · Round #1105 (Div. 2) · Problem B ↗

Problem

Given integers n,m,r,cn, m, r, c (1≤r≤n≤109, 1≤c≤m≤109)(1 \leq r \leq n \leq 10^9,\ 1 \leq c \leq m \leq 10^9).

An n×mn \times m binary matrix of 00's and 11's is valid if every contiguous submatrix of size r×cr \times c has a total xor of 00.

How many valid binary matrices are there? (Modulo 998244353998244353.)

Initial Observations
  1. Binary.
  2. Xor's.
  3. Construction.
  4. Everything seems "fixed" once you've chosen some cells.
  5. Greed?
  6. Fix r⋅c−1r \cdot c - 1 cells?
IdeaFix some cells freely, the rest are forcedAC

Pretty quickly I figured you might be able to set a few cells freely as either 00 or 11, which would force other cells to a single value (the only choice that makes the xor equal 00). Then, with a sweep of sorts, you might be able to find them all.

Key Observation

Look at the top-left r×cr \times c submatrix. If you arbitrarily select all r⋅cr \cdot c cells except one — say the bottom-right cell (r,c)(r, c) — then the value of that cell is forced: there is exactly one choice that makes the xor of the submatrix 00.

Key Observation

Once the top-left r×cr \times c submatrix is fixed, slide the window one step to the right (or down). Most of the cells inside are already decided — only the newly entered column (or row) is undecided. Choose all of its cells freely except the bottom-right one, which the xor rule forces. Repeat until the window reaches the edge, in both directions.

Draw a Picture

At this point, it's easier to look at an example of what happens as you slide. Here's a 5×65 \times 6 matrix (n=5n = 5, m=6m = 6) with a 2×32 \times 3 window (r=2r = 2, c=3c = 3).

Legend:   ·  free choice (0 or 1)      x  forced by the xor rule
          .  not yet decided          +--+  the current window
 
Step 1 — the top-left 2x3 window: pick 5 cells freely, the 6th is forced
 
    +----------+
    | ·  ·  ·  | .  .  .
    | ·  ·  x  | .  .  .
    +----------+
      .  .  .    .  .  .
      .  .  .    .  .  .
      .  .  .    .  .  .
 
Step 2 — slide right one: only the entering column is new; its bottom
cell is forced, the rest chosen freely
 
       +----------+
     · | ·  ·  ·  | .  .
     · | ·  x  x  | .  .
       +----------+
      .  .  .  .    .  .
 
Step 3 — after sliding across the whole top: a row of x's emerges
 
      ·  ·  ·  ·  ·  ·
      ·  ·  x  x  x  x
      .  .  .  .  .  .
 
Step 4 — same idea sliding down from the top-left: a column of x's
 
      ·  ·  ·  ·  ·  ·
      ·  ·  x  x  x  x
      ·  ·  x  .  .  .
      ·  ·  x  .  .  .
      ·  ·  x  .  .  .
 
Step 5 — slide into the remaining region (bottom-right corner of each
window placement is always the only unknown): everything else is forced
 
      ·  ·  ·  ·  ·  ·
      ·  ·  x  x  x  x
      ·  ·  x  x  x  x
      ·  ·  x  x  x  x
      ·  ·  x  x  x  x

After doing this, you'll see the top rows and left columns were chosen arbitrarily, and the x's fill in the rest: every remaining window placement has its bottom-right corner as the only unknown cell, so sliding the window over the whole matrix forces everything else.

Key Observation

In the end, every cell at position (i,j)(i, j) with i≥ri \geq r and j≥cj \geq c is forced — an (n−r+1)×(m−c+1)(n - r + 1) \times (m - c + 1) rectangle of forced cells anchored at the bottom-right corner. All other cells (the top r−1r - 1 rows and the left c−1c - 1 columns) can be chosen freely.

Write It Out

The formula becomes clear from here: 22 choices for every free cell, exactly one choice for every forced cell.

ALL=n⋅mFORCED=(n−r+1)(m−c+1)FREE=ALL−FORCEDCHOICES=2FREE=2 nm − (n−r+1)(m−c+1)\begin{aligned} \text{ALL} &= n \cdot m \\ \text{FORCED} &= (n - r + 1)(m - c + 1) \\ \text{FREE} &= \text{ALL} - \text{FORCED} \\ \text{CHOICES} &= 2^{\text{FREE}} = 2^{\,n m \,-\, (n - r + 1)(m - c + 1)} \end{aligned}

Since nn and mm can be up to 10910^9 (so the exponent can be around 101810^{18}), and everything is modulo 998244353998244353, you cannot exponentiate naively.

Draw from Experience

You can compute ab mod pa^b \bmod p in O(log⁡b)O(\log b) time with fast exponentiation (repeated squaring).

Algorithm
PRIME = 998244353
 
def pow2(e):                    # 2^e mod PRIME by repeated squaring
    res, base = 1, 2
    while e:
        if e % 2: res = res * base % PRIME
        base = base * base % PRIME
        e //= 2
    return res
 
def solve(n, m, r, c):
    total  = n * m                        # 64-bit: up to ~10^18
    forced = (n - r + 1) * (m - c + 1)
    free   = total - forced
    return pow2(free)
Generate and Test

The first idea I had turned out to be the right one, so I started from it and checked that it worked, which led us here.

Examine Examples

The sliding observation felt relatively obvious to me, but getting it exactly right meant checking a few low-hanging examples (including the sample test cases), along with drawing it out and writing out the formula.

Review

The answer is 2 nm−(n−r+1)(m−c+1) mod 9982443532^{\,nm - (n-r+1)(m-c+1)} \bmod 998244353, computed with fast exponentiation in O(log⁡(nm))O(\log(nm)). The path:

  1. One cell per window is forced. In the top-left r×cr \times c window, choose all cells but one freely — the last is forced by the xor rule. [1]
  2. Slide the window. Each step right or down introduces one new column or row: all of it is free except the bottom-right cell of the window, which is forced. Sweeping the window over the whole matrix decides every cell. [2]
  3. The forced region is a rectangle. Exactly the cells (i,j)(i, j) with i≥ri \geq r and j≥cj \geq c are forced — (n−r+1)(m−c+1)(n-r+1)(m-c+1) of them; the rest are free. [3]
  4. Count the choices: 22 per free cell, so 2 nm−(n−r+1)(m−c+1)2^{\,nm - (n-r+1)(m-c+1)} — with the exponent up to ∼1018\sim 10^{18}, computed by repeated squaring modulo 998244353998244353.

References

Problem-solving techniques used:

Generate and Test

The problem was straightforward enough that the first idea turned out to be correct; I mostly spent the time verifying the exact mechanics to reach the final formula.

Draw a Picture

This problem became relatively easy once I drew out exactly what happens as the rectangle slides — key to seeing that the block from (r,c)(r, c) to (n,m)(n, m) is completely forced and everything else is free.

Examine Examples

The small test cases were good for getting a feel for it all.

Write It Out

Getting the formula exactly right was a matter of just writing it down cleanly.

Draw from Experience

Fast exponentiation is a standard technique that should be in any competitive programmer's "book of code."

Learning points:

Topics: