Gale-Ryser Theorem

Правка en25, от Noobish_Monk, 2026-02-16 21:28:14

This blog is a submission for the Third Codeforces Month of Blog Posts, thanks to cadmiumky for the initiative!

Thanks to TeaTime and k1r1t0 for giving feedback on the post.


Hi everyone!

I want to talk about Gale-Ryser Theorem and some of its applications. I've provided proofs for each fact in the blog, they're hidden under the spoilers.


Gale-Ryser Theorem

We have an array of $$$n$$$ non-negative integers $$$a_1, a_2, \ldots, a_n$$$ and an array of $$$m$$$ positive integers $$$b_1, b_2, \ldots, b_m$$$, $$$b_i \le n$$$. The array $$$b$$$ describes a sequence of operations, in the $$$i$$$-th operation we need to decrease the values at $$$b_i$$$ positions by $$$1$$$, formally pick $$$b_i$$$ unique indices $$$j_1, j_2, \ldots, j_{b_i}$$$ and decrease $$$a_{j_p}$$$ by $$$1$$$ for $$$1 \le p \le b_i$$$. We want to know if it's possible to have all $$$a_i \ge 0$$$ after the operations.

Without loss of generality $$$b_1 \ge b_2 \ge \ldots \ge b_m$$$. The Theorem says that it's possible iff $$$\sum \limits_{i=1}^k \min(a_i, k) \ge \sum \limits_{j=1}^k b_j$$$ for $$$\forall 1 \le k \le m$$$.

Necessity
Sufficiency

Proof by induction also suggests a strategy for the construction, which turns out to be the natural greedy strategy — always selecting $$$b_i$$$ maximum positions. However, the proof by induction requires us to do the operations in decreasing order. While it doesn't follow from this proof, it's actually not needed to sort $$$b$$$ to run the greedy. In other words, the order of operations doesn't matter, if we always pick only the maximum positions.

Proof that order of operations doesn't matter

Tasks for practice

Problem from AtCoder ABC

Problem from JOISC 2023

1740F - Conditional Mix


An important special case, all $$$b_i = t$$$. That is, in each of $$$m$$$ operations times $$$t$$$ positions are decreased. Then it is only needed to check that $$$\sum \limits_{i=1}^n \min(t, a_i) \ge mt$$$

Proof

Another example is 1774B - Coloring. Here's the short statement: we have $$$n$$$ cells and $$$m$$$ colors, each cell must be colored. For each color there must be exactly $$$a_i$$$ cells painted with that color ($$$\sum a = n$$$). Also, every window of given size $$$k$$$ cannot have cells of one color.

Solution (yes, editorial for div2B)

Here is a problem where you can try applying the idea yourself 1893D - Colorful Constructive


Dual

There is also a dual version of this problem. Suppose on each operation we decrease at most $$$b_i$$$ elements by $$$1$$$, but the goal now is to get all $$$a_i = 0$$$. Just swap $$$a$$$ and $$$b$$$ and we'll get the same problem as before! Originally all $$$b_j$$$ required $$$b_j$$$ positions in $$$a$$$ and each position $$$a_i$$$ could've been picked at most $$$a_i$$$ times. And here each $$$a_i$$$ must be picked exactly $$$a_i$$$ times (we need to pick exactly $$$a_i$$$ positions in $$$b$$$) and each $$$b_j$$$ can be picked at most $$$b_j$$$ times.

Sometimes all of the operations are the same. Usually in this case we want to find the minimum number of operations $$$m$$$ which we need to make all $$$a_i = 0$$$. Suppose all operations decrease at most $$$t$$$ positions. How do we find the $$$m$$$?

Solution

Right now I can only remember this problem 2181G - Greta's Game, which uses this fact, but this idea appears sometimes, usually where $$$t = 2$$$.

Also an application of this idea in Meta Hacker Cup, problem B


Lastly, there is problem D2 from Open Olympiad 24-25 day 2 XIX Open Olympiad in Informatics - Final Stage, Day 2 (Unrated, Online Mirror, IOI rules), which motivated me to understand this theorem. The fact below is crucial for the solution, so it's under a spoiler as well.

Fact

История

 
 
 
 
Правки
 
 
  Rev. Язык Кто Когда Δ Комментарий
en25 Английский Noobish_Monk 2026-02-16 21:28:14 19 Tiny change: '/6339)\n\n---\n\' -> '/6339)\n\n[problem:1740F]\n\n---\n\'
en24 Английский Noobish_Monk 2026-02-10 15:28:01 0 (published)
en23 Английский Noobish_Monk 2026-02-10 15:27:20 1
en22 Английский Noobish_Monk 2026-02-10 15:27:11 102
en21 Английский Noobish_Monk 2026-02-10 15:25:51 83 Tiny change: 'tCoder ABC which uses the Theorem](https://' -> 'tCoder ABC](https://'
en20 Английский Noobish_Monk 2026-02-10 15:21:51 430 Tiny change: 'm from JOI](https://' -> 'm from JOISC 2023](https://'
en19 Английский Noobish_Monk 2026-02-10 02:33:38 9130 Tiny change: '+ k_2 \ge x$, then:\' -> '+ k_2 \ge c_x$, then:\'
en18 Английский Noobish_Monk 2026-02-08 15:50:16 361 Tiny change: '1893D]\n\nDual\n' -> '1893D]\n\n---\n\nDual\n'
en17 Английский Noobish_Monk 2026-01-28 23:58:37 393
en16 Английский Noobish_Monk 2026-01-28 03:41:24 2700 Tiny change: 'reases $x - 1$.\n\n![' -> 'reases $x + 1$.\n\n!['
en15 Английский Noobish_Monk 2026-01-27 21:30:10 553 Tiny change: 'Hi everyon' -> 'Your title here...\n==================\n==================Hi everyon'
en14 Английский Noobish_Monk 2026-01-22 14:59:31 4
en13 Английский Noobish_Monk 2026-01-22 14:58:20 2
en12 Английский Noobish_Monk 2026-01-22 14:57:20 835
en11 Английский Noobish_Monk 2026-01-22 14:29:26 2760 Tiny change: '+ a_2$\n\n...\n\n$k = t' -> '+ a_2$\n\n$\ldots$\n\n$k = t'
en10 Английский Noobish_Monk 2026-01-21 02:04:54 402
en9 Английский Noobish_Monk 2026-01-20 21:49:06 353 Tiny change: 'we can add$m — k$ minimu' -> 'we can add $m - k$ minimu'
en8 Английский Noobish_Monk 2026-01-19 20:09:57 803 Tiny change: 'g m \cdot (time to get count and sum))$' -> 'g m \cdot $(time to get certain sum)$)$'
en7 Английский Noobish_Monk 2026-01-19 19:37:06 1773 Tiny change: 'k = 1 \Rigtharrow m \g' -> 'k = 1 \Rightarrow m \g'
en6 Английский Noobish_Monk 2026-01-19 17:16:29 3 Tiny change: ' for div2B">\nFor ea' -> ' for div2B)">\nFor ea'
en5 Английский Noobish_Monk 2026-01-19 17:14:46 2624 Tiny change: 'oiler>\n\n' -> 'oiler>\n\n\n=================='
en4 Английский Noobish_Monk 2026-01-19 16:00:44 1269 Tiny change: 'er an $S\\T$ cut. Sp' -> 'er an $S\\ T$ cut. Sp'
en3 Английский Noobish_Monk 2026-01-19 14:52:31 1831 Tiny change: 'oiler>\n\n' -> 'oiler>\n\n<spoiler summary="Sufficiency">\n...\n</spoiler>'
en2 Английский Noobish_Monk 2026-01-19 14:32:50 568 Tiny change: '_j$ for $\all 1 \le ' -> '_j$ for $\forall 1 \le '
en1 Английский Noobish_Monk 2026-01-19 14:21:30 592 Initial revision (saved to drafts)