跳转至

# 卡特兰数

## 引入

Catalan 数经常出现在各类计数问题中．比利时数学家 Eugène Charles Catalan 在 1958 年研究括号序列计数问题时发现了这一数列，它也因此得名．清朝数学家明安图早在 18 世纪 30 年代就已经发现这一数列．

Catalan 数满足如下递推关系：

𝐶 𝑛={1,𝑛=0,∑𝑛−1 𝑖=0 𝐶 𝑖 𝐶 𝑛−1−𝑖,𝑛>0.(1)(1)C n={1,n=0,∑i=0 n−1 C i C n−1−i,n>0.

数列的前几项为：（OEIS: A000108，下标从 0 0 开始）

1,1,2,5,1 4,4 2,1 3 2,4 2 9,1 4 3 0,…1,1,2,5,14,42,132,429,1430,…

## 应用

Catalan 数 𝐶 𝑛 C n 的递推关系有着天然的递归结构：规模为 𝑛 n 的计数问题 𝐶 𝑛 C n，可以通过枚举分界点，分拆为两个规模分别为 𝑖 i 和 (𝑛 −1 −𝑖)(n−1−i) 的子问题．这一递推关系使得 Catalan 数广泛出现于各类具有类似递归结构的问题中．

- 路径计数问题：有一个大小为 𝑛 ×𝑛 n×n 的方格图，左下角为 (0,0)(0,0)，右上角为 (𝑛,𝑛)(n,n)．从左下角开始，每次都只能向右或者向上走一单位，不走到对角线 𝑦 =𝑥 y=x 上方（但可以触碰）的情况下，到达右上角的路径总数为 𝐶 𝑛 C n．

  证明

  设方案数为 𝑇 𝑛 T n．考虑 𝑛 ≥2 n≥2 的情况．设路径 第一次 走到对角线 𝑦 =𝑥 y=x 的点是 (𝑘,𝑘) (𝑘 ∈[1,𝑛])(k,k) (k∈[1,n])．考察从 (0,0)(0,0) 到 (𝑘,𝑘)(k,k) 的除起点和终点外，中间的点 不经过对角线（不能碰到） 的路径．

  如图所示，这些路径的第一步一定向右，从 (0,0)(0,0) 到 (1,0)(1,0)；最后一步一定向上，从 (𝑘,𝑘 −1)(k,k−1) 到 (𝑘,𝑘)(k,k)．因此，这些路径就是从 (1,0)(1,0) 到 (𝑘,𝑘 −1)(k,k−1) 的不越过直线 𝑦 =𝑥 −1 y=x−1 的路径，这样路径的数目就是 𝑇 𝑘−1 T k−1．同时，从 (𝑘,𝑘)(k,k) 到 (𝑛,𝑛)(n,n) 的合法路径数就是 𝑇 𝑛−𝑘 T n−k．根据乘法原理，第一次在 (𝑘,𝑘)(k,k) 处触碰对角线的路径数目为 𝑇 𝑘−1 𝑇 𝑛−𝑘 T k−1 T n−k．枚举 𝑘 k 的所有可能性，所有合法路径的数目为

  𝑇 𝑛=𝑛∑𝑘=1 𝑇 𝑘−1 𝑇 𝑛−𝑘.T n=∑k=1 n T k−1 T n−k.

  做代换 𝑘 =𝑖 +1 k=i+1 就可以发现，这就是 Catalan 数的递推关系．由 𝑇 0 =1 T 0=1 可知 𝑇 𝑛 =𝐶 𝑛 T n=C n．

- 圆内不相交弦计数问题：圆上有 2 𝑛 2 n 个点，将这些点成对连接起来且使得所得到的 𝑛 n 条线段两两不交的方案数是 𝐶 𝑛 C n．

  证明

  记 2 𝑛 2 n 个点的方案数为 𝑇 𝑛 T n．将 2 𝑛 2 n 个点按顺时针标号，分别为 1,2,…,2 𝑛 1,2,…,2 n．由于弦两两不交，1 1 号点只能连接偶数号点；否则，两点之间的奇数个点无法在不穿过两点连线的情况下两两配对．如果连接了 1 1 和 2 𝑘 (𝑘 ∈[1,𝑛])2 k (k∈[1,n])，那么左边有 2 𝑘 −2 2 k−2 个点，右边有 2 𝑛 −2 𝑘 2 n−2 k 个点，由乘法原理，这样的方案数为 𝑇 𝑘−1 𝑇 𝑛−𝑘 T k−1 T n−k．因此，枚举 𝑘 k，有 𝑇 𝑛 =∑𝑛 𝑘=1 𝑇 𝑘−1 𝑇 𝑛−𝑘 T n=∑k=1 n T k−1 T n−k．令 𝑘 =𝑖 +1 k=i+1，就得到 Catalan 数的递推关系．由 𝑇 0 =1 T 0=1 可知 𝑇 𝑛 =𝐶 𝑛 T n=C n．

- 三角剖分计数问题：对角线不相交的情况下，将一个凸 (𝑛 +2)(n+2) 边形区域分成三角形区域的方法数为 𝐶 𝑛 C n．

  证明

  设 (𝑛 +2)(n+2) 边形三角剖分的方案数为 𝑇 𝑛 T n．先选定一条边 (1,𝑛 +2)(1,n+2) 作为基边，它一定属于一个三角形，记该三角形的第三个点为 𝑘 (𝑘 ∈[2,𝑛 +1])k (k∈[2,n+1])．这样，原凸多边形变成了三个部分：

  - 三角形 (1,𝑘,𝑛 +2)(1,k,n+2)．
  - 𝑘 k 边形，顶点 1 ∼𝑘 1∼k．
  - (𝑛 +3 −𝑘)(n+3−k) 边形，顶点 𝑘 ∼(𝑛 +2)k∼(n+2)．

  后面两个部分都是子问题，所以，有递推关系

  𝑇 𝑛=𝑛+1∑𝑘=2 𝑇 𝑘−2 𝑇 𝑛+1−𝑘.T n=∑k=2 n+1 T k−2 T n+1−k.

  令 𝑘 =𝑖 +2 k=i+2，就得到 Catalan 数递归关系．由 𝑇 0 =𝑇 1 =1 T 0=T 1=1 可知 𝑇 𝑛 =𝐶 𝑛 T n=C n．

- 二叉树计数问题：含有 𝑛 n 个结点的形态不同的二叉树数目为 𝐶 𝑛 C n．等价地，含有 𝑛 n 个非叶结点的形态不同的满二叉树数目为 𝐶 𝑛 C n．

  证明

  记 𝑛 n 个结点的二叉树数目为 𝑇 𝑛 T n．任取一个根结点，枚举左右子树大小．设左子树大小为 𝑖 ∈[0,𝑛 −1]i∈[0,n−1]，则右子树大小为 (𝑛 −1 −𝑖)(n−1−i)．左右子树均为子问题，所以，有递推关系

  𝑇 𝑛=𝑛−1∑𝑖=0 𝑇 𝑖 𝑇 𝑛−1−𝑖.T n=∑i=0 n−1 T i T n−1−i.

  这就是 Catalan 数递推关系．由 𝑇 0 =𝑇 1 =1 T 0=T 1=1 可知 𝑇 𝑛 =𝐶 𝑛 T n=C n．

- 括号序列计数问题：由 𝑛 n 对括号构成的合法括号序列数为 𝐶 𝑛 C n．

  证明

  联系路径计数问题．将左括号视为向上走，右括号视为向右走．合法括号序列即为，在任意位置，左括号的数量不少于右括号的数量．相当于路径计数问题中，在任意时刻，向上走的次数不少于向右走的次数．因此，合法括号序列与合法路径之间存在双射．合法括号序列的数目同样为 𝐶 𝑛 C n．

- 出栈序列计数问题：一个栈（无穷大）的进栈序列为 1,2,3,…,𝑛 1,2,3,…,n，合法出栈序列的数目为 𝐶 𝑛 C n．

  证明

  联系括号序列计数问题．将入栈视为左括号，出栈视为右括号．任意时刻，入栈的次数不少于出栈的次数．因此，合法出栈序列与合法括号序列之间存在双射．合法出栈序列的数目同样为 𝐶 𝑛 C n．

- 数列计数问题：由 𝑛 n 个 +1+1 和 𝑛 n 个 −1−1 组成的数列 𝑎 1,𝑎 2,…,𝑎 2 𝑛 a 1,a 2,…,a 2 n 中，部分和满足 𝑎 1 +𝑎 2 +… +𝑎 𝑘 ≥0 (𝑘 =1,2,3,…,2 𝑛)a 1+a 2+…+a k≥0 (k=1,2,3,…,2 n) 的数列数目为 𝐶 𝑛 C n．

  证明

  联系括号序列计数问题．将 +1+1 视为左括号，−1−1 视为右括号．任意时刻，+1+1 的数量不少于 −1−1 的数量．因此，合法数列与合法括号序列之间存在双射．合法数列的数目同样为 𝐶 𝑛 C n．

尽管这一递推关系应用广泛，但是直接计算复杂度较高，需要寻找更为简单的公式．

## 常见形式

Catalan 数有如下常见的表达式：

𝐶 𝑛=1 𝑛+1(2 𝑛 𝑛)=(2 𝑛)!𝑛!(𝑛+1)!, 𝑛≥0.(2)(2)C n=1 n+1(2 n n)=(2 n)!n!(n+1)!, n≥0.𝐶 𝑛=(2 𝑛 𝑛)−(2 𝑛 𝑛+1), 𝑛≥0.(3)(3)C n=(2 n n)−(2 n n+1), n≥0.𝐶 𝑛=(4 𝑛−2)𝑛+1 𝐶 𝑛−1, 𝑛>0, 𝐶 0=1.(4)(4)C n=(4 n−2)n+1 C n−1, n>0, C 0=1.

Catalan 数的这些形式都可以高效计算：前两个形式将它转换为阶乘和组合数的计算问题，第三个形式则提供了顺次计算的递推公式．

对于这三种常见形式，本文提供两种证明方式．

### 代数推演

通过代数方法得出 Catalan 数的上述表达式共两步．首先，验证三个形式相互等价．

证明表达式 (2) ∼(4)(2)∼(4) 等价

只需要证明表达式 (3)(3) 可以转化为表达式 (2)(2) 中阶乘形式：

𝐶 𝑛=(2 𝑛 𝑛)−(2 𝑛 𝑛+1)=(2 𝑛)!𝑛!𝑛!−(2 𝑛)!(𝑛−1)!(𝑛+1)!=(2 𝑛)!𝑛!𝑛!(1−𝑛!(𝑛−1)!(𝑛+1))=(2 𝑛)!𝑛!𝑛!(1−𝑛 𝑛+1)=(2 𝑛)!𝑛!(𝑛+1)!.C n=(2 n n)−(2 n n+1)=(2 n)!n!n!−(2 n)!(n−1)!(n+1)!=(2 n)!n!n!(1−n!(n−1)!(n+1))=(2 n)!n!n!(1−n n+1)=(2 n)!n!(n+1)!.

以及，表达式 (4)(4) 也可以转化为表达式 (2)(2) 中阶乘形式：

𝐶 𝑛=𝑛∏𝑖=1(4 𝑖−2)𝑖+1=𝑛∏𝑖=1 2 𝑖(2 𝑖−1)𝑖(𝑖+1)=(2 𝑛)!𝑛!(𝑛+1)!.C n=∏i=1 n(4 i−2)i+1=∏i=1 n 2 i(2 i−1)i(i+1)=(2 n)!n!(n+1)!.

因此，三个表达式互相等价．

紧接着，验证这些形式确实是 Catalan 数递推公式的解．为此，考虑使用生成函数方法直接求出递推公式 (1)(1) 的解．

利用生成函数方法求解递推公式 (1)(1)

考虑 Catalan 数的普通生成函数 𝐶(𝑥) =∑∞𝑛=0 𝐶 𝑛 𝑥 𝑛 C(x)=∑n=0∞C n x n．由于 Catalan 数的递推关系和卷积形式很相似，所以考虑用卷积构造 𝐶(𝑥)C(x) 的方程：

𝐶(𝑥)=∞∑𝑛=0 𝐶 𝑛 𝑥 𝑛=1+∞∑𝑛=1(𝑛−1∑𝑖=0 𝐶 𝑖 𝐶 𝑛−𝑖−1)𝑥 𝑛=1+𝑥∞∑𝑛=1 𝑛−1∑𝑖=0 𝐶 𝑖 𝑥 𝑖 𝐶 𝑛−𝑖−1 𝑥 𝑛−𝑖−1=1+𝑥∞∑𝑖=0 𝐶 𝑖 𝑥 𝑖∞∑𝑗=0 𝐶 𝑗 𝑥 𝑗=1+𝑥 𝐶 2(𝑥).C(x)=∑n=0∞C n x n=1+∑n=1∞(∑i=0 n−1 C i C n−i−1)x n=1+x∑n=1∞∑i=0 n−1 C i x i C n−i−1 x n−i−1=1+x∑i=0∞C i x i∑j=0∞C j x j=1+x C 2(x).

其中，倒数第二个等号交换了求和次序，并令 𝑗 =𝑛 −1 −𝑖 j=n−1−i．由此，解得：

𝐶(𝑥)=1±√1−4 𝑥 2 𝑥=2 1∓√1−4 𝑥.C(x)=1±1−4 x 2 x=2 1∓1−4 x.

由初值条件 𝐶 0 =1 C 0=1 可知，𝐶(0) =1 C(0)=1．代入检验可以发现唯一可行的解就是

𝐶(𝑥)=1−√1−4 𝑥 2 𝑥.C(x)=1−1−4 x 2 x.

接下来，需要将它展开为幂级数的形式．利用 (1 +𝑥)𝑎(1+x)a 的 幂级数展开式 可知：

√1−4 𝑥=∞∑𝑛=0(1 2)−𝑛 𝑛!(−4 𝑥)𝑛,1−4 x=∑n=0∞(1 2)−n n!(−4 x)n,

其中，(1 2)−𝑛(1 2)−n 是下降阶乘幂：

(1 2)−𝑛=𝑛−1∏𝑘=0(1 2−𝑘)=1 2 𝑛 𝑛−1∏𝑘=1(1−2 𝑘)=(−1)𝑛−1 2 𝑛 𝑛−1∏𝑘=1(2 𝑘−1)=(−1)𝑛−1 2 2 𝑛−1 𝑛−1∏𝑘=1(2 𝑘−1)2 𝑘 𝑘=(−1)𝑛−1 2 2 𝑛−1(2 𝑛−2)!(𝑛−1)!.(1 2)−n=∏k=0 n−1(1 2−k)=1 2 n∏k=1 n−1(1−2 k)=(−1)n−1 2 n∏k=1 n−1(2 k−1)=(−1)n−1 2 2 n−1∏k=1 n−1(2 k−1)2 k k=(−1)n−1 2 2 n−1(2 n−2)!(n−1)!.

代入 𝐶(𝑥)C(x) 的表达式，就有

𝐶(𝑥)=1 2 𝑥(1−∞∑𝑛=0(1 2)−𝑛 𝑛!(−4 𝑥)𝑛)=−1 2 𝑥∞∑𝑛=1(−4 𝑥)𝑛 𝑛!(1 2)−𝑛=−1 2 𝑥∞∑𝑛=1(−4 𝑥)𝑛 𝑛!(−1)𝑛−1 2 2 𝑛−1(2 𝑛−2)!(𝑛−1)!=∞∑𝑛=1(2 𝑛−2)!(𝑛−1)!𝑛!𝑥 𝑛−1=∞∑𝑛=0(2 𝑛)!𝑛!(𝑛+1)!𝑥 𝑛.C(x)=1 2 x(1−∑n=0∞(1 2)−n n!(−4 x)n)=−1 2 x∑n=1∞(−4 x)n n!(1 2)−n=−1 2 x∑n=1∞(−4 x)n n!(−1)n−1 2 2 n−1(2 n−2)!(n−1)!=∑n=1∞(2 n−2)!(n−1)!n!x n−1=∑n=0∞(2 n)!n!(n+1)!x n.

由此，就得到 𝐶 𝑛 C n 的表达式 (2)(2)．

### 组合意义

由于 Catalan 数具有明显的组合意义，所以只使用组合计数方法同样可以证明这些形式．本节为三个表达式分别提供一个组合意义的证明．

表达式 (2)(2) 的证明

考虑 数列计数问题．对于任意由 ±1±1 组成的序列 {𝑎 𝑖}2 𝑛 𝑖=1{a i}i=1 2 n，定义它的部分和为 𝑆 𝑖 =∑𝑖 𝑗=1 𝑎 𝑖 S i=∑j=1 i a i，并定义它的 超额量（exceedance）为 𝑆 𝑖 <0 S i<0 且 𝑎 𝑖 = −1 a i=−1 的下标数量．超额量为 0 0，就等价于数列合法；超额量的取值范围是 [0,𝑛][0,n]，共 (𝑛 +1)(n+1) 种可能的取值．需要证明的是，不同超额量的数列数量其实是一样的．

为此，可以构造一个从超额量为 𝑒 >0 e>0 的数列到超额量为 (𝑒 −1)(e−1) 的数列的映射 𝑓 f．对于超额量为 𝑒 >0 e>0 的序列 {𝑎 𝑖}{a i}，取下标 𝑘 k 为使得 𝑆 𝑖 =0 S i=0 且 𝑎 𝑖 = +1 a i=+1 成立的下标最小值．将 𝑎 𝑘 a k 左右两侧的序列交换，就得到如下序列 {𝑎′𝑖}{a i′}：

𝑎 𝑘+1,𝑎 𝑘+2,⋯,𝑎 2 𝑛,𝑎 𝑘,𝑎 1,𝑎 2,⋯,𝑎 𝑘−1.a k+1,a k+2,⋯,a 2 n,a k,a 1,a 2,⋯,a k−1.

由于原序列中 𝑎 𝑘 a k 右侧部分在交换前后对应的部分和序列不变，所以它们贡献的超额量也不变．对于原序列中 𝑎 𝑘 a k 左侧部分，它们对应的部分和在交换后全部增加 1 1，因此，它们贡献的超额量会减少，而且减少的数量恰好等于原序列 𝑎 𝑘 a k 左侧部分中满足 𝑆 𝑖 = −1 S i=−1 且 𝑎 𝑖 = −1 a i=−1 的下标数量．因为 𝑎 𝑘 a k 的选取保证了这样的下标有且仅有一个，所以，序列 {𝑎′𝑖}{a i′} 的超额量就等于 (𝑒 −1)(e−1)．也就是说，映射 𝑓 f 可以将序列的超额量恰好减少 1 1．

映射 𝑓 f 是可逆的．注意到序列 {𝑎′𝑖}{a i′} 中，𝑎 𝑘 a k 对应的位置恰好为满足 𝑆′𝑘 = +1 S k′=+1 且 𝑎′𝑖 = +1 a i′=+1 的下标最大值．这是因为交换后，这些部分和都比交换前对应的部分和恰好大 1 1，因此，现在的部分和为 +1+1 对应交换前部分和等于 0 0．但是，根据 𝑘 k 的选取，交换前这一部分（即原序列 𝑎 𝑘 a k 左侧部分）是没有满足 𝑆 𝑖 =0 S i=0 且 𝑎 𝑖 = +1 a i=+1 成立的下标的．

由此，映射 𝑓 f 构成了超额量为 𝑒 >0 e>0 的序列和超额量为 (𝑒 −1)(e−1) 的序列之间的双射．这就说明，不同超额量的数列数量其实是一样的．由于数列总数是 (2 𝑛 𝑛)(2 n n)，合法数列（即超额量为 0 0 的数列）数量就等于

𝐶 𝑛=1 𝑛+1(2 𝑛 𝑛).C n=1 n+1(2 n n).

这就证明了 Catalan 数的表达式 (2)(2)．

表达式 (3)(3) 的证明

考虑 路径计数问题．这是典型的格路计数问题，可以通过反射原理求解．具体到本问题，考虑用总路径数目减去不合法的路径数目．总路径数一共要走 2 𝑛 2 n 步，其中 𝑛 n 步向右，所以方案数为 (2 𝑛 𝑛)(2 n n)．一条路径不合法，当且仅当它碰到了直线 𝑦 =𝑥 +1 y=x+1．对于任意一条非法路径，可以找到第一次碰到直线 𝑦 =𝑥 +1 y=x+1 的位置，并将该位置之后的路径关于直线 𝑦 =𝑥 +1 y=x+1 做对称．此时，可以发现，一条从 (0,0)(0,0) 到 (𝑛,𝑛)(n,n) 的非法路径，变成了一条从 (0,0)(0,0) 到 (𝑛 −1,𝑛 +1)(n−1,n+1) 的路径．

由于从 (0,0)(0,0) 到 (𝑛 −1,𝑛 +1)(n−1,n+1) 的路径必定要穿过直线 𝑦 =𝑥 +1 y=x+1，所以每条这样的路径都对应一条从 (0,0)(0,0) 到 (𝑛,𝑛)(n,n) 的非法路径．类似总路径数的计算，非法路径数目的总数就是 (2 𝑛 𝑛+1)(2 n n+1)．因此，合法路径的总数为

𝐶 𝑛=(2 𝑛 𝑛)−(2 𝑛 𝑛+1).C n=(2 n n)−(2 n n+1).

这就是 Catalan 数的表达式 (3)(3)．

表达式 (4)(4) 的证明

考虑 三角剖分计数问题．设 𝑃 P 是凸 (𝑛 +2)(n+2) 边形，固定它的一个边为基边．对于多边形 𝑃 P 的每一个三角剖分，都可以选择它的一个非基边（包括三角剖分时新加的边）标记，并定向．这共有 (4 𝑛 +2)𝐶 𝑛(4 n+2)C n 种剖分加标记的方案．又设 𝑄 Q 是凸 (𝑛 +3)(n+3) 边形，仍固定它的一个边为基边．对于多边形 𝑄 Q，可以选择它的一条非基边标记，然后再做三角剖分．这共有 (𝑛 +2)𝐶 𝑛+1(n+2)C n+1 种标记加剖分的方案．

如图所示，这两组操作得到的结果之间存在明显的双射．对于 𝑃 P 剖分并标记的一个结果，可以将它的标记边扩展为三角形，定向所指向的终点扩展为一条新边，并将这条新边打上标记，这就得到对 𝑄 Q 标记并剖分的一个结果；对于 𝑄 Q 标记并剖分的一个结果，可以将它的标记边压缩为一个点，并将压缩得到的对角线打上标记，且指向压缩得到的顶点，这就得到对 𝑃 P 剖分并标记的一个结果．因此，

(4 𝑛+2)𝐶 𝑛=(𝑛+2)𝐶 𝑛+1.(4 n+2)C n=(n+2)C n+1.

稍作整理，并结合 𝐶 0 =1 C 0=1，就得到 Catalan 数的表达式 (4)(4)．

## 例题

洛谷 P1044 栈

入栈顺序为 1,2,…,𝑛 1,2,…,n，求所有可能的出栈顺序的总数．

参考代码
C++Python

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    #include <iostream>
    using namespace std;

    int n;
    long long f[25];

    int main() {
      f[0] = 1;
      cin >> n;
      for (int i = 1; i <= n; i++) f[i] = f[i - 1] * (4 * i - 2) / (i + 1);
      // 这里用的是常见形式 4
      cout << f[n] << endl;
      return 0;
    }

    1
    2
    3
    4
    5
    6
    7
    f = [0] * 25
    f[0] = 1
    n = int(input())
    for i in range(1, n + 1):
        f[i] = f[i - 1] * (4 * i - 2) // (i + 1)
        # 这里用的是常见形式 4
    print(f[n])

## 习题

- Luogu P2532 [AHOI2012] 树屋阶梯
- Luogu P1641 [SCOI2010] 生成字符串
- Luogu P3200 [HNOI2009] 有趣的数列
- AtCoder Beginner Contest 205 E - White and Black Balls
- AtCoder Regular Contest 145 C - Split and Maximize
- Luogu P5014 水の三角（修改版）
- Luogu P3978 [TJOI2015] 概率论

## 参考资料与注释

- Catalan number - Wikipedia

> 本页面最近更新：2026/1/7 08:56:54，更新历史
> 发现错误？想一起完善？ 在 GitHub 上编辑此页！
> 本页面贡献者：Ir1d, StudyingFather, H-J-Granger, countercurrent-time, Enter-tainer, NachtgeistW, Xeonacid, MegaOwIer, Tiphereth-A, AngelKitty, c-forrest, CCXXXI, cjsoft, diauweb, Early0v0, ezoixx130, GekkaSaori, Konano, ksyx, LovelyBuggies, Makkiy, mgt, minghu6, P-Y-Y, PotassiumWings, SamZhangQingChuan, sshwy, Suyun514, weiyong1024, Chrogeek, Fidelxyz, GavinZhengOI, Gesrua, Great-designer, Henry-ZHR, HeRaNO, hsfzLZH1, iamtwz, kenlig, kfy666, kxccc, lychees, Marcythm, Menci, Peanut-Tang, purple-vine, refinedcoding, shawlleyw, ShizuhaAki, Skyminers, SukkaW, ucSec, WFHFAQFXY, xglight, zryi2003
> 本页面的全部内容在 CC BY-SA 4.0 和 SATA 协议之条款下提供，附加条款亦可能应用