A - Snack

题意

dd 天,每天可以选择花费 1/3/4/61/3/4/6 元购买四种不同的零食,求 dd 天总共恰好花费 nn 元的购买方案数。

两个购买方案不同当且仅当存在一天购买的零食不同.

d2×105,n106d\le 2\times 10^5, n\le 10^6

解法

定义

普通生成函数(OGF):一个序列 an\left\langle a_n\right\rangle 的 OGF 是一个形式幂级数(可以看作无限长的多项式)A(x)=i=0aixiA(x) = \sum_{i=0}^{\infty} a_i x^i,其中 aia_i 是数列的第 ii 项。

通过类比一般多项式的乘法,可以得到 OGF 的加法和乘法。

a,ba,b 的 OGF 分别是 F(x),G(x)F(x), G(x),则:

  • OGF 的加法:F(x)+G(x)F(x) + G(x) 对应的数列是 an+bn\left\langle a_n + b_n \right\rangle
  • OGF 的乘法:F(x)G(x)F(x) G(x) 对应的数列是 i=0naibni\langle \sum_{i=0}^n a_i b_{n-i} \rangle

在形式幂级数中,我们不关心 xx 的具体取值,只关心系数的含义,就相当于把系数挂在了一个多项式上,再用这个多项式去进行进一步的各种计算。

而多项式的乘法就是一种卷积,当我们要找 x2x^2 的系数时,就是找 x0x^0x2x^2 的系数相乘加上 x1x^1x1x^1 的系数相乘再加上 x2x^2x0x^0 的系数相乘。这正好对应了把总数为 22 的物品分成两部分去计数的过程。所以,我们要把花费放在指数上,而方案放在系数上,这样就可以通过多项式乘法来进行计数。

举例:
33 块红色的地砖和 22 块蓝色的地砖,求选出 44 块地砖的方案数(两个方案不同当且仅当选出的红砖个数不同或选出的蓝砖数量不同)。

手动枚举一下,可能的方案只有 (3,1),(2,2)(3,1),(2,2),所以答案是 22

用 OGF 解决这个问题,写出红色地砖的 OGF:R(x)=1+x+x2+x3R(x) = 1 + x + x^2 + x^3,表示选 0/1/2/30/1/2/3 块红色地砖的方案数分别是 1/1/1/11/1/1/1。蓝色地砖的 OGF 是 B(x)=1+x+x2B(x) = 1 + x + x^2。所以最后的答案就是 [x4]R(x)B(x)[x^4]R(x)B(x),其中 [xn]F(x)[x^n]F(x) 表示形式幂级数 F(x)F(x)xnx^n 的系数。相乘,结果为 R(x)B(x)=1+2x+3x2+3x3+2x4+x5R(x)B(x) = 1 + 2x + 3x^2 + 3x^3 + 2x^4 + x^5,所以答案是 22

可以发现,我们顺带求出了需要选出任意块地砖的各自方案数。

回到本题,我们的序列第 ii 个元素表示花费 ii 元的购买方案数。则每一天的 OGF 就是 x+x3+x4+x6x+x^3+x^4+x^6,因为每一天可以选择花费 1/3/4/61/3/4/6 元购买零食。

所以总花费就是第一天花费加第二天花费加 \ldots 加第 dd 天花费,对应的 OGF 就是 (x+x3+x4+x6)d(x+x^3+x^4+x^6)^d。因为每一天的选择规则都一样,且第一天的选择和第二天的选择是独立的,根据乘法原理,总方案数的 OGF 就是 dd 个每天的 OGF 相乘。

那么,答案就是 [xn](x+x3+x4+x6)d[x^n](x+x^3+x^4+x^6)^d

后面稍微进行一些代数变形即可解决本题:

[xn](x+x3+x4+x6)d=[xnd](1+x2+x3+x5)d=[xnd](1+x2)d(1+x3)d\begin{aligned} [x^n](x+x^3+x^4+x^6)^d &= [x^{n-d}](1+x^2+x^3+x^5)^d \\ &= [x^{n-d}](1+x^2)^d(1+x^3)^d\\ \end{aligned}

我们只需要枚举左边的项每一次的系数,就知道右边项对应的系数,通过二项式定理计算就可以解决本题。

答案即为

i,jN,2i+3j=nd(di)(dj)\sum_{i,j\in \mathbb N, 2i+3j = n-d} \binom{d}{i} \binom{d}{j}

复杂度 O(d)O(d)

参考代码


B - Tuple of Integers

题意

给定 nn,求满足条件的非负整数四元组 (a,b,c,d)(a,b,c,d) 个数:

  • a+b+c+d=na+b+c+d = n
  • a{0,1}a\in \{0, 1\}
  • b{0,1,2}b\in \{0, 1, 2\}
  • cc 是偶数;
  • dd 是 3 的倍数。

0n1090\le n\le 10^9

解法

一样的,写出每一个数的 OGF:
A(x)=1+xA(x) = 1 + xB(x)=1+x+x2B(x) = 1 + x + x^2C(x)=1+x2+x4+C(x) = 1 + x^2 + x^4 + \ldotsD(x)=1+x3+x6+D(x) = 1 + x^3 + x^6 + \ldots

高中等比数列求和有如下公式:

i=0a1qi=a11q(q<1)\sum_{i=0}^{\infty} a_1 q^i = \dfrac{a_1}{1-q} \quad (|q|<1)

现在 C(x)C(x)D(x)D(x) 是无穷级数,我们类比等比数列求和可以把它们写成封闭形式。

C(x)=i=0x2i=11x2D(x)=i=0x3i=11x3\begin{aligned} C(x) = \sum_{i=0}^{\infty} x^{2i} &= \dfrac{1}{1-x^2}\\ D(x) = \sum_{i=0}^{\infty} x^{3i} &= \dfrac{1}{1-x^3} \end{aligned}

在对形式幂级数进行运算时,我们不关心级数的敛散性,只关心每一项系数,所以可以直接使用这个公式, 11x2\dfrac{1}{1-x^2} 虽然看上去不像一个幂级数,但是它在形式幂级数的意义下,就是 i=0x2i\sum_{i=0}^{\infty} x^{2i}。 在运算时,使用分式会更加方便,我们也把这种形式叫做原来幂级数的封闭形式。

所以答案就是

[xn]A(x)B(x)C(x)D(x)=[xn](1+x)(1+x+x2)(1x2)(1x3)=[xn]1(1x)2\begin{aligned} [x^n]A(x)B(x)C(x)D(x) &= [x^n]\dfrac{(1+x)(1+x+x^2)}{(1-x^2)(1-x^3)}\\ &= [x^n]\dfrac{1}{(1-x)^2} \end{aligned}

接下来我们介绍如何求 [xn]1(1x)k[x^n]\dfrac{1}{(1-x)^k}。一个简单的方法是使用牛顿二项式定理(或泰勒展开),但是我们在此给出一种组合意义证明。

1(1x)k=(n=0xn)k\dfrac{1}{(1-x)^k} = \left(\sum_{n=0}^{\infty} x^n\right)^k,我们考察 xnx^n 的系数如何来的,就是要在每个括号中选择一个次数,使得总和为 nn。这就相当于把 nn 个相同的球放入 kk 个不同的盒子中,允许某些盒子为空。根据插板法,答案就是 (n+k1k1)\dbinom{n+k-1}{k-1}

回到原题,答案就是 (n+2121)=n+1\dbinom{n+2-1}{2-1} = n+1

参考代码


C - Sequence

题意

求满足条件的长度为 nn 的序列个数:

  • 每个元素是不大于 mm 的非负整数;
  • 总和为 ss

n,m,s2×105n,m,s\le 2\times 10^5

解法

答案是 [xs](1+x++xm)n[x^s](1+x+\ldots+x^m)^n

进行代数变形:

[xs](1+x++xm)n=[xs](1xm+11x)n=[xs](1xm+1)n(1x)n.\begin{aligned} [x^s](1+x+\ldots+x^m)^n = [x^s]\left(\dfrac{1-x^{m+1}}{1-x}\right)^n = [x^s](1-x^{m+1})^n(1-x)^{-n}. \end{aligned}

之后只需要枚举两边系数即可,左右的系数我们都已经会处理了,答案就是

k=0n(1)k(nk)(sk(m+1)+n1n1).\sum_{k=0}^{n} (-1)^k \binom{n}{k} \binom{s -k(m+1) + n - 1}{n - 1}.

参考代码


D - Sequence 2

题意

求满足条件的长度为 nn 的序列个数:

  • 每个元素是不大于 mm 的非负整数;
  • 所有元素按从大到小排序之后,相邻的数奇偶性不同。

n,m2×105n,m\le 2\times 10^5

解法

对原数组 a\left\langle a\right\rangle 排完序之后得到 b\left\langle b\right\rangle,考虑 b\left\langle b\right\rangle 的差分序列 d\left\langle d\right\rangle

di={b1,i=1bibi1i>1d_i = \begin{cases} b_1, & i = 1\\ b_i - b_{i-1} & i > 1 \end{cases}

因为每个数都不同,只需要计算差分序列的个数,再乘以 n!n! 即可。

差分序列的条件如下:

  • d1d_1 是非负整数;
  • d2,d3,dnd_2, d_3, \ldots d_n 是正奇数;
  • d1+d2++dnmd_1 + d_2 + \ldots + d_n \le m

因此,这样的差分序列个数就是

i=0m[xi]11x(x1x2)n1=[xmn+1]1(1x)n+1(1+x)n1.\sum_{i=0}^m [x^i] \dfrac{1}{1-x} \left(\dfrac{x}{1-x^2}\right)^{n-1} = [x^{m-n+1}] \dfrac{1}{(1-x)^{n+1}(1+x)^{n-1}}.

(此处用到了如下性质:i=0m[xi]F(x)=[xm]F(x)1x\sum_{i=0}^m [x^i]F(x) = [x^m]\dfrac{F(x)}{1-x},可以把 11x\dfrac{1}{1-x} 看作一个前缀和算子)

参考代码


E - Sequence 3

题意

求满足条件的长度为 nn 的序列个数:

  • 每个元素是不大于 mm 的正整数;
  • ii 最多出现了 ii 次。

n,m300n,m \le 300

解法

为解决本题,我们要介绍一种新的生成函数——指数生成函数(EGF)。

定义
指数生成函数(EGF):一个序列 an\left\langle a_n\right\rangle 的 EGF 是一个形式幂级数 A(x)=i=0aixii!A(x) = \displaystyle\sum_{i=0}^{\infty} a_i \dfrac{x^i}{i!},其中 aia_i 是数列的第 ii 项。

可以得到 EGF 的加法和乘法的运算法则。
a,ba,b 的 EGF 分别是 F(x),G(x)F(x), G(x),则:

  • EGF 的加法:F(x)+G(x)F(x) + G(x) 对应的数列是 an+bn\left\langle a_n + b_n \right\rangle
  • EGF 的乘法:F(x)G(x)F(x) G(x) 对应的数列是 i=0n(ni)aibni\left\langle \sum_{i=0}^n \dbinom{n}{i} a_i b_{n-i} \right\rangle

我们发现,EGF 的乘法对应了不同物品组合的方案,也就自动解决了有序的问题。

写出每一个数的 EGF:Fk(x)=i=0kxii!F_k(x) = \displaystyle\sum_{i=0}^{k} \dfrac{x^i}{i!}. 答案就是 [xnn!]i=1mFi(x)\left[\dfrac{x^n}{n!}\right] \displaystyle\prod_{i=1}^{m} F_i(x)

多项式用 NTT 做乘法,复杂度就是 O(nmlogn)O(nm \log n)

参考代码

https://atcoder.jp/contests/fps-24/submissions/72985819