Hi everyone!
Thanks to K1o0n and Noobish_Monk for the round. This problem looks scary at first, but the final idea is short. I will explain it slowly, step by step, so even beginners can follow. If something is unclear, ask in the comments!
What does the problem ask?
We have a table of numbers with
Unable to parse markup [type=CF_MATHJAX]
$ rows and
Unable to parse markup [type=CF_MATHJAX]
$ columns. Pick any rectangle inside it (a "submatrix"). Let its height be
Unable to parse markup [type=CF_MATHJAX]
$, its width be
Unable to parse markup [type=CF_MATHJAX]
$, and the sum of its numbers be
Unable to parse markup [type=CF_MATHJAX]
$.
- If
Unable to parse markup [type=CF_MATHJAX]
$ is even, its price is
Unable to parse markup [type=CF_MATHJAX]
$. - If
Unable to parse markup [type=CF_MATHJAX]
$ is odd, its price is
Unable to parse markup [type=CF_MATHJAX]
$.
We need the total price of all rectangles, modulo
Unable to parse markup [type=CF_MATHJAX]
$. Also
Unable to parse markup [type=CF_MATHJAX]
$, so we need roughly an
Unable to parse markup [type=CF_MATHJAX]
$ solution.
Why is brute force too slow?
A table has about
Unable to parse markup [type=CF_MATHJAX]
$ rectangles. For
Unable to parse markup [type=CF_MATHJAX]
$ that is far too many. We need a smarter idea.
Let's try a tiny example first
Take one row with 3 numbers:
Unable to parse markup [type=CF_MATHJAX]
$. The rectangles are:
- length 1 (even sum of sizes):
Unable to parse markup [type=CF_MATHJAX]
$ - length 2 (odd):
Unable to parse markup [type=CF_MATHJAX]
$ - length 3 (even):
Unable to parse markup [type=CF_MATHJAX]
$
If you expand and add everything, almost all terms cancel and you get:
Unable to parse markup [type=CF_MATHJAX]
$
**The middle number
Unable to parse markup [type=CF_MATHJAX]
$ disappeared completely!** Only the 1st and 3rd numbers matter. This tells us that most of the stuff cancels out, and we just need to find what survives.
Step 1: Break
Unable to parse markup [type=CF_MATHJAX]
$ into pairs
Unable to parse markup [type=CF_MATHJAX]
$ means "sum of all numbers" times "sum of all numbers". So
Unable to parse markup [type=CF_MATHJAX]
$ is the sum of
Unable to parse markup [type=CF_MATHJAX]
$ over every pair of cells
Unable to parse markup [type=CF_MATHJAX]
$ inside the rectangle (the pair
Unable to parse markup [type=CF_MATHJAX]
$ and
Unable to parse markup [type=CF_MATHJAX]
$ both count, and
Unable to parse markup [type=CF_MATHJAX]
$ is allowed).
Now flip the viewpoint:
Instead of "for each rectangle, look at all pairs inside it", do "for each pair of cells, look at all rectangles that contain both".
So for each pair we only need the total of signs of all rectangles containing both cells. Call it
Unable to parse markup [type=CF_MATHJAX]
$. Then
Unable to parse markup [type=CF_MATHJAX]
$
Step 2: Rows and columns are independent
A rectangle is chosen by top row
Unable to parse markup [type=CF_MATHJAX]
$, bottom row
Unable to parse markup [type=CF_MATHJAX]
$, left column
Unable to parse markup [type=CF_MATHJAX]
$, right column
Unable to parse markup [type=CF_MATHJAX]
$. The sign is
Unable to parse markup [type=CF_MATHJAX]
$
because
Unable to parse markup [type=CF_MATHJAX]
$ and
Unable to parse markup [type=CF_MATHJAX]
$ (the
Unable to parse markup [type=CF_MATHJAX]
$s cancel in pairs and the minus signs don't change parity).
So the sign splits into a row part and a column part, and
Unable to parse markup [type=CF_MATHJAX]
$. We can handle rows alone, then columns alone.
Step 3: Solve the rows (columns are the same)
Let the two cells have rows with smaller value
Unable to parse markup [type=CF_MATHJAX]
$ and larger value
Unable to parse markup [type=CF_MATHJAX]
$. To contain both cells, the rectangle needs
Unable to parse markup [type=CF_MATHJAX]
$ and
Unable to parse markup [type=CF_MATHJAX]
$. So
Unable to parse markup [type=CF_MATHJAX]
$
These are sums like
Unable to parse markup [type=CF_MATHJAX]
$, where neighbours cancel:
- First part:
Unable to parse markup [type=CF_MATHJAX]
$ up to
Unable to parse markup [type=CF_MATHJAX]
$. If
Unable to parse markup [type=CF_MATHJAX]
$ is even, everything cancels and it's
Unable to parse markup [type=CF_MATHJAX]
$. If
Unable to parse markup [type=CF_MATHJAX]
$ is odd, one
Unable to parse markup [type=CF_MATHJAX]
$ is left, so it's
Unable to parse markup [type=CF_MATHJAX]
$. - Second part: sum from
Unable to parse markup [type=CF_MATHJAX]
$ to
Unable to parse markup [type=CF_MATHJAX]
$. If
Unable to parse markup [type=CF_MATHJAX]
$ and
Unable to parse markup [type=CF_MATHJAX]
$ have different parity, the count of terms is even and it cancels to
Unable to parse markup [type=CF_MATHJAX]
$. If they have the same parity, one term is left and it's
Unable to parse markup [type=CF_MATHJAX]
$.
Conclusion for rows: the pair contributes only if - the smaller row is odd, and - the larger row has the **same parity as
Unable to parse markup [type=CF_MATHJAX]
$**.
In that case
Unable to parse markup [type=CF_MATHJAX]
$. Columns work the same way with
Unable to parse markup [type=CF_MATHJAX]
$.
Multiplying:
Unable to parse markup [type=CF_MATHJAX]
$. This is a constant, so
Unable to parse markup [type=CF_MATHJAX]
$
That is why the code ends with: "if
Unable to parse markup [type=CF_MATHJAX]
$ is odd, negate the total".
Check with our example
Unable to parse markup [type=CF_MATHJAX]
$ (
Unable to parse markup [type=CF_MATHJAX]
$,
Unable to parse markup [type=CF_MATHJAX]
$): a pair is valid if the smaller column is odd and the larger column is odd. The valid column pairs are
Unable to parse markup [type=CF_MATHJAX]
$, which gives
Unable to parse markup [type=CF_MATHJAX]
$. ✓
Step 4: Add up the valid pairs fast
We still can't check all pairs (too slow), so we use prefix sums.
For a pair of cells, one of them is "up/left" and the other is "down/right" in terms of the roles of min and max. Depending on whether
Unable to parse markup [type=CF_MATHJAX]
$ or
Unable to parse markup [type=CF_MATHJAX]
$ holds the smaller row, and whether
Unable to parse markup [type=CF_MATHJAX]
$ or
Unable to parse markup [type=CF_MATHJAX]
$ holds the smaller column, there are exactly 4 cases:
| Case | Cell 1 must be | Cell 2 must be | Where cell 2 is |
|---|---|---|---|
| 1 | row odd, col odd | row ≡ n, col ≡ m | down and right (can touch) |
| 2 | row odd, col odd | row ≡ n, col ≡ m | strictly down and strictly right |
| 3 | row odd, col ≡ m | row ≡ n, col odd | down and strictly left |
| 4 | row odd, col ≡ m | row ≡ n, col odd | strictly down, same column or left |
(In cases 2 and 4 cell 1 is the "other" cell of the pair, so the ordered pair is counted from the other side. The "strict" versus "can touch" choices make sure no pair is counted twice when two cells share a row or column.)
For each cell in the table, we need:
"the sum of all good cells in the region down-right (or down-left) of me"
That is exactly what a 2D suffix sum gives in
Unable to parse markup [type=CF_MATHJAX]
$. We build two tables:
S0: suffix sums going down-right over cells with row ≡ n and column ≡ m.S1: suffix sums going down-left over cells with row ≡ n and column odd.
Then for every cell with an odd row, we multiply its value by the right table lookup for each case and add it to total.
Complexity
- Time:
Unable to parse markup [type=CF_MATHJAX]
$ per test - Memory:
Unable to parse markup [type=CF_MATHJAX]
$
The sum of
Unable to parse markup [type=CF_MATHJAX]
$ over all tests is at most
Unable to parse markup [type=CF_MATHJAX]
$, so this runs comfortably








