Partition Numbers

Partitions: a representation of a natural number nn as a sum of positive integers in non-increasing order.

n=r1+r2+…+rkr1≥r2≥…≥rk≥1n=r_1+r_2+\ldots+r_k \quad r_1 \ge r_2 \ge \ldots \ge r_k \ge 1

Each positive integer in the sum is called a part.

Partition numbers: pnp_n, the number of ways to partition the natural number nn.

Partition numbers starting from 00:

n012345678
pnp_n112357111522

Partitions into k Parts

A partition of nn into exactly kk parts is called a partition into kk parts, denoted by p(n,k)p(n,k).

Clearly, the number of partitions into kk parts, p(n,k)p(n,k), is also the number of solutions of the following equation:

n−k=y1+y2+…+yky1≥y2≥…≥yk≥0n-k=y_1+y_2+\ldots+y_k\quad y_1\ge y_2\ge\ldots\ge y_k\ge 0

If exactly jj parts in this equation are nonzero, then there are exactly p(n−k,j)p(n-k,j) solutions. Therefore,

p(n,k)=∑j=0kp(n−k,j)p(n,k)=\sum_{j=0}^k p(n-k,j)

Subtracting two adjacent sums gives

p(n,k)=p(n−1,k−1)+p(n−k,k)p(n,k)=p(n-1,k-1)+p(n-k,k)

If we lay out a table, the number in each cell equals the number in the upper-left cell plus the numbers in the column-number-many cells above that cell.

k012345678
p(0,k)p(0,k)100000000
p(1,k)p(1,k)010000000
p(2,k)p(2,k)011000000
p(3,k)p(3,k)011100000
p(4,k)p(4,k)012110000
p(5,k)p(5,k)012211000
p(6,k)p(6,k)013321100
p(7,k)p(7,k)013432110
p(8,k)p(8,k)014553211

Example

Computing the Number of Partitions into k Parts

Compute the number of partitions into kk parts, p(n,k)p(n,k). There are multiple test cases; nn is at most 1000010000, kk is at most 10001000, and all answers are taken modulo 10000071000007.

Looking at the table and recurrence, updating by column is more favorable for storage. The program is straightforward:

#include <cstdio>
#include <cstring>

int p[10005][1005]; /*Number of ways to partition the natural number n into k parts*/

int main() {
  int n, k;
  while (~scanf("%d%d", &n, &k)) {
    memset(p, 0, sizeof(p));
    p[0][0] = 1;
    int i;
    for (i = 1; i <= n; ++i) {
      int j;
      for (j = 1; j <= k; ++j) {
        if (i - j >= 0) /*All parts of p[i-j][j] are greater than 1*/
        {
          p[i][j] = (p[i - j][j] + p[i - 1][j - 1]) %
                    1000007; /*p[i-1][j-1] has at least one part equal to 1.*/
        }
      }
    }
    printf("%d\n", p[n][k]);
  }
}

Generating Function

By the formula for the sum of a geometric progression,

11−xk=1+xk+x2k+x3k+…\frac{1}{1-x^k}=1+x^k+x^{2k}+x^{3k}+\ldots 1+p1x+p2x2+p3x3+…=11−x11−x211−x3…1+p_1 x+p_2 x^2+p_3 x^3+\ldots=\frac{1}{1-x} \frac{1}{1-x^2} \frac{1}{1-x^3}\ldots

For partitions into kk parts, the generating function is slightly more complicated. Explicitly,

∑n,k=0∞p(n,k)xnyk=11−xy11−x2y11−x3y…\sum_{n,k=0}^\infty {p(n,k) x^n y^k }=\frac{1}{1-xy} \frac{1}{1-x^2 y} \frac{1}{1-x^3 y}\ldots

Ferrers Diagram

A Ferrers diagram represents each part of a partition as a row of dots. The number of dots in each row is the size of that part.

By the definition of a partition, the different rows in a Ferrers diagram are arranged in decreasing order. The longest row is at the top.

For example, the Ferrers diagram of the partition 12=5+4+2+112=5+4+2+1 is as follows.

Figure: ferrers

Flipping a Ferrers diagram along its diagonal produces a new Ferrers diagram called the conjugate of the original diagram, and the new partition is called the conjugate of the original partition. Clearly, conjugation is a symmetric relation.

For example, the conjugate of the partition 12=5+4+2+112=5+4+2+1 above is the partition 12=4+3+2+2+112=4+3+2+2+1.

The number of partitions with largest part kk is the number of partitions of the natural number nn whose largest part is kk.

By the definition of conjugation, we immediately obtain:

The number of partitions with largest part kk is equal to the number of partitions into kk parts; both are p(n,k)p(n,k).

Partitions into Distinct Parts

The number of partitions into distinct parts: pdnpd_n, the number of ways to partition the natural number nn so that all parts are distinct. (Different)

n012345678
pdnpd_n111223456

Similarly, define the number of partitions into kk distinct parts, pd(n,k)pd(n,k), as the number of distinct partitions into exactly kk parts; it is the number of solutions of

n=r1+r2+…+rkr1>r2>…>rk≥1n=r_1+r_2+\ldots+r_k\quad r_1>r_2>\ldots>r_k\ge 1

Equivalently, it is the number of solutions of

n−k=y1+y2+…+yky1>y2>…>yk≥0n-k=y_1+y_2+\ldots+y_k\quad y_1>y_2>\ldots>y_k\ge 0

The difference from the discussion above is that, because the parts are distinct, the new equation has at most one zero part. The same invariant conclusion holds: if exactly jj parts are not 00, then there are exactly pd(n−k,j)pd(n-k,j) solutions, where jj can only be kk or k−1k-1. Thus we directly obtain the recurrence

pd(n,k)=pd(n−k,k−1)+pd(n−k,k)pd(n,k)=pd(n-k,k-1)+pd(n-k,k)

As with binomial coefficients, we can lay out a table. The number in each cell equals the numbers in the column-number-many cells above the cell in the preceding column, plus the numbers in the column-number-many cells above the cell.

k012345678
pd(0,k)pd(0,k)100000000
pd(1,k)pd(1,k)010000000
pd(2,k)pd(2,k)010000000
pd(3,k)pd(3,k)011000000
pd(4,k)pd(4,k)011000000
pd(5,k)pd(5,k)012000000
pd(6,k)pd(6,k)012100000
pd(7,k)pd(7,k)013100000
pd(8,k)pd(8,k)013200000

Example

Computing the Number of Partitions into Distinct Parts

Compute the number of partitions into distinct parts, pdnpd_n. There are multiple test cases; nn is at most 5000050000, and all answers are taken modulo 10000071000007.

Looking at the table and recurrence, updating by column is more favorable for storage. The code saves space by reducing the latter dimension to two, retaining only adjacent terms.

#include <cstdio>
#include <cstring>

int pd[50005][2]; /*Number of distinct ways to partition the natural number n into k parts*/

int main() {
  int n;
  while (~scanf("%d", &n)) {
    memset(pd, 0, sizeof(pd));
    pd[0][0] = 1;
    int ans = 0;
    int j;
    for (j = 1; j < 350; ++j) {
      int i;
      for (i = 0; i < 350; ++i) {
        pd[i][j & 1] = 0; /*pd[i][j] depends only on pd[][j] and pd[][j-1]*/
      }
      for (i = 0; i <= n; ++i) {
        if (i - j >= 0) /*All parts of pd[i-j][j] are greater than 1*/
        {
          pd[i][j & 1] = (pd[i - j][j & 1] + pd[i - j][(j - 1) & 1]) %
                         1000007; /*pd[i-j][j-1] has at least one part equal to 1.*/
        }
      }
      ans = (ans + pd[n][j & 1]) % 1000007;
    }
    printf("%d\n", ans);
  }
}

Partitions into Odd Parts

The number of partitions into odd parts: ponpo_n, the number of ways to partition the natural number nn so that every part is odd. (Odd)

There is an obvious identity:

∏i=1∞(1+xi)=∏i=1∞(1−x2i)∏i=1∞(1−xi)=∏i=1∞11−x2i−1\prod_{i=1}^\infty (1+x^i ) =\frac{\prod_{i=1}^\infty (1-x^{2i} ) }{\prod_{i=1}^\infty (1-x^i ) }=\prod_{i=1}^\infty \frac{1}{1-x^{2i-1} }

The leftmost expression is the generating function for partitions into distinct parts, and the rightmost expression is the generating function for partitions into odd parts. Their corresponding coefficients are equal, so the numbers of partitions into odd parts and into distinct parts are equal:

pon=pdnpo_n=pd_n

However, the number of partitions into kk odd parts and the number of partitions into kk distinct parts are clearly different concepts, so we omit the former here.

We introduce two more concepts:

The number of partitions into distinct even parts: pdenpde_n, the number of distinct partitions of the natural number nn with an even number of parts. (Even)

The number of partitions into distinct odd parts: pdonpdo_n, the number of distinct partitions of the natural number nn with an odd number of parts. (Odd)

Therefore,

pdn=pden+pdonpd_n=pde_n+pdo_n

There are corresponding notions for partitions into kk parts as well. They are too complicated to list here.

The Pentagonal Number Theorem

Consider separately the denominator of the generating function for partition numbers:

∏i=1∞(1−xi)\prod_{i=1}^\infty (1-x^i )

Expanding this expression brings to mind partitions into distinct parts and the parity of their number of parts.

Specifically, partitions into a distinct even number of parts are counted positively in the expansion, while partitions into a distinct odd number of parts are counted negatively. Therefore, each coefficient in the expansion is the difference between the two counts. That is,

∑i=0∞(pden−pdon)xn=∏i=1∞(1−xi)\sum_{i=0}^\infty ({pde}_n-{pdo}_n ) x^n =\prod_{i=1}^\infty (1-x^i )

We next show that in most cases the two counts above are equal, so the coefficient in the expansion is 00; only at a few positions do the two counts differ by 11 or −1-1.

Here we can construct a correspondence.

Draw the Ferrers diagram of each distinct partition. The last row is called the base of the diagram, and let bb (Bottom) be the number of dots on the base. The longest 4545-degree line segment connecting the last dot of the top row to a dot in the diagram is called the slide of the diagram, and let ss (Slide) be the number of dots on the slide.

Figure: bottom slide

To construct a correspondence between partitions into a distinct even number of parts and partitions into a distinct odd number of parts, define transformations that change the number of rows by 11 while preserving distinctness:

Transformation A: when bb is less than or equal to ss, move the base to the right, making it a new slide.

Transformation B: when bb is greater than ss, move the slide to the bottom, making it a new base.

For any distinct partition of most nn, exactly one of these two transformations can be performed, thereby constructing a bijection between partitions into a distinct even number of parts and partitions into a distinct odd number of parts. Since a bijection has been constructed, the numbers of the two types of partitions are equal, and the coefficient of the nn-th term in the expansion is 00.

However, for some nn, there is exactly one distinct partition for which neither of the transformations above can be performed.

  • Case 1: when b=sb=s and the base and slide have one common point, Transformation A cannot be performed. In this case,
n=s+(s+1)+…+(s+s−1)=s(3s−1)2n=s+(s+1)+\ldots+(s+s-1)=\frac{s(3s-1)}{2}

The nn-th term of the expansion depends on the parity of the number of parts in the partition and is (−1)sxn(-1)^s x^n.

  • Case 2: when b=s+1b=s+1 and the base and slide have one common point, Transformation B cannot be performed. In this case,
n=(s+1)+(s+2)+…+(s+s)=s(3s+1)2n=(s+1)+(s+2)+\ldots+(s+s)=\frac{s(3s+1)}{2}

The nn-th term of the expansion is (−1)sxn(-1)^s x^n.

Using −s-s in place of the ss in the formula above gives n=s(3s−1)2n=\frac{s(3s-1)}{2}, where ss is a negative integer, and the nn-th term of the expansion is still (−1)sxn(-1)^s x^n.

Since the two cases cannot occur for the same nn, we can combine the two conditions. The condition on nn is

∃k∈Z,n=k(3k−1)2\exists k\in\mathbb{Z},n=\frac{k(3k-1)}{2}

We have therefore proved:

(1−x)(1−x2)(1−x3)…=∑k=−∞+∞(−1)kxk(3k−1)2=…+x26−x15+x7−x2+1−x+x5−x12+x22−…(1-x)(1-x^2 )(1-x^3 )\ldots=\sum_{k=-\infty}^{+\infty} (-1)^k x^{\frac{k(3k-1)}{2}} =\ldots+x^{26}-x^{15}+x^7-x^2+1-x+x^5-x^{12}+x^{22}-\ldots

Recall that this expression is the reciprocal of the generating function for partition numbers, so multiplying it by the generating function for partition numbers gives 11. Rearranging and comparing the coefficients on both sides gives the recurrence for the sequence of partition numbers.

(1+p1x+p2x2+p3x3+…)(1−x−x2+x5+x7−x12−x15+x22+x26−…)=1(1+p_1 x+p_2 x^2+p_3 x^3+\ldots)(1-x-x^2+x^5+x^7-x^{12}-x^{15}+x^{22}+x^{26}-\ldots)=1 pn=pn−1+pn−2−pn−5−pn−7+…p_n=p_{n-1}+p_{n-2}-p_{n-5}-p_{n-7}+\ldots

This recurrence has infinitely many terms, but if we define the number of partitions of a negative number to be 00 (the number of partitions of 00 has already been defined as 11), it simplifies to finitely many terms.

Example

Computing Partition Numbers

Compute the partition number pnp_n. There are multiple test cases; nn is at most 5000050000, and all answers are taken modulo 10000071000007.

Use the pentagonal number theorem. The code is as follows:

#include <cstdio>

long long a[100010];
long long p[50005];

int main() {
  p[0] = 1;
  p[1] = 1;
  p[2] = 2;
  int i;
  for (i = 1; i < 50005;
       i++) /*Recurrence coefficients 1,2,5,7,12,15,22,26...i*(3*i-1)/2,i*(3*i+1)/2*/
  {
    a[2 * i] = i * (i * 3 - 1) / 2; /*Pentagonal numbers are 1,5,12,22...i*(3*i-1)/2*/
    a[2 * i + 1] = i * (i * 3 + 1) / 2;
  }
  for (
      i = 3; i < 50005;
      i++) /*p[n]=p[n-1]+p[n-2]-p[n-5]-p[n-7]+p[12]+p[15]-...+p[n-i*[3i-1]/2]+p[n-i*[3i+1]/2]*/
  {
    p[i] = 0;
    int j;
    for (j = 2; a[j] <= i; j++) /*The result may be negative; add 1000007 in the formula*/
    {
      if (j & 2) {
        p[i] = (p[i] + p[i - a[j]] + 1000007) % 1000007;
      } else {
        p[i] = (p[i] - p[i - a[j]] + 1000007) % 1000007;
      }
    }
  }
  int n;
  while (~scanf("%d", &n)) {
    printf("%lld\n", p[n]);
  }
}

This content comes from OI Wiki: Partition Numbers. See the original for authors and revision history. AIOJ has adapted the formatting, in-site links, and resource paths.

Content is shared under CC BY-SA 4.0 and SATA license; additional terms are governed by the original notice. Thanks to the OI Wiki authors and contributors; per the SATA terms, please visit the OI Wiki repository and star it to show your support.