A
卡到心态爆炸的一个题;推了好久最后还是推不出
2
17
2^{17}
217, 最后直接prt(2^(2n - 3))
了。
有一些组合数学的证明办法:
生成函数
红球蓝球生成函数取
1
+
x
2
2
!
+
x
4
4
!
+
…
1 + \frac{x^2}{2!}+ \frac{x^4}{4!}+\dots
1+2!x2+4!x4+…,该级数可写为
e
x
+
e
−
x
2
\frac{e^x+e^{-x}}{2}
2ex+e−x
黑球白球取
x
+
x
3
3
!
+
…
x+\frac{x^3}{3!}+\dots
x+3!x3+…,该级数可以写为
e
x
−
e
−
x
2
\frac{e^x-e^{-x}}{2}
2ex−e−x
所以最终只需要求 ( e x + e − x 2 ) 2 ( e x − e − x 2 ) 2 (\frac{e^x+e^{-x}}{2})^2(\frac{e^x-e^{-x}}{2})^2 (2ex+e−x)2(2ex−e−x)2展开式中项 x n n ! \frac{x^n}{n!} n!xn的系数即可。
因为组合数学还没有好好学…(我真的来不及qwq)…所以大概理解了一下后认为,生成函数只是关心指数之和为一定值,利用系数自动累加求和的性质来快速求一些和为一定值的组合方案数。因而我们不需要考虑生成函数中 1 n ! \frac1{n!} n!1的影响,只需要对指数的情况考虑即可。
之后将上式化简后找到 x n n ! \frac{x^n}{n!} n!xn的系数即可得到答案。
UPD:
稍微看了看《组合数学》完善了一下这一块的理论证明。
上述组合计数问题的解决办法是是指数生成函数
。
如果采用普通的生成函数办法,其生成函数就会写为:
(
1
+
x
2
+
x
4
+
…
)
2
(
x
+
x
3
+
x
5
+
…
)
2
=
(
1
1
−
x
2
)
2
(
x
1
−
x
2
)
2
(1+x^2+x^4+\dots)^2(x+x^3+x^5+\dots)^2=(\frac{1}{1-x^2})^2(\frac{x}{1-x^2})^2
(1+x2+x4+…)2(x+x3+x5+…)2=(1−x21)2(1−x2x)2
这个函数如果能求得泰勒展开后 x n x^n xn的系数,那么该系数计数方法也是正确的。
问题在于这个函数的n阶导数并没有太大的规律性以至于求解困难,所以我们需要采用另一种生成方法。
我们用指数生成函数方法: 有序列 h 0 , h 1 , h 2 , … h_0, h_1, h_2,\dots h0,h1,h2,…那么定义它的指数生成函数是 g ( x ) = ∑ i = 0 ∞ h i x i i ! g(x) = \sum_{i=0}^{∞}h_i\frac{x^i}{i!} g(x)=i=0∑∞hii!xi
对于指数生成函数,有一个重要的定理,这个定理也解释了之前我所考虑的 1 n ! \frac1{n!} n!1的求和问题。
定理
设
S
S
S是多重集合
{
n
1
⋅
a
1
,
n
2
⋅
a
2
,
…
,
n
k
⋅
a
k
}
\{ n_1 \cdot a_1, n_2\cdot a_2,\dots,n_k\cdot a_k \}
{n1⋅a1,n2⋅a2,…,nk⋅ak},其中
n
i
n_i
ni为非负整数,表示元素的个数。设
h
n
h_n
hn是
S
S
S的
n
n
n排列数,那么数列
h
0
,
h
1
,
h
2
,
…
h_0, h_1, h_2,\dots
h0,h1,h2,…的指数生成函数为:
g
(
e
)
(
x
)
=
f
n
1
(
x
)
f
n
2
(
x
)
…
f
n
k
(
x
)
g^{(e)}(x)=f_{n_1}(x)f_{n_2}(x)\dots f_{n_k}(x)
g(e)(x)=fn1(x)fn2(x)…fnk(x)
其中,对于
i
=
1
,
2
,
…
,
k
i=1,2,\dots, k
i=1,2,…,k,有
f
n
i
(
x
)
=
∑
i
=
0
n
i
x
i
i
!
f_{n_i}(x)= \sum_{i=0}^{n_i}\frac{x^i}{i!}
fni(x)=i=0∑nii!xi
证明
非常巧妙漂亮 值得学习!
当我们把生成函数拆开后,考虑下面的这一项:
x
m
1
m
1
!
x
m
2
m
2
!
…
x
m
k
m
k
!
=
x
m
1
+
m
2
+
⋯
+
m
k
m
1
!
m
2
!
…
m
k
!
\frac{x^{m_1}}{m_1!}\frac{x^{m_2}}{m_2!}\dots \frac{x^{m_k}}{m_k!}=\frac{x^{m_1+m_2+\dots+m_k}}{m_1!m_2!\dots m_k!}
m1!xm1m2!xm2…mk!xmk=m1!m2!…mk!xm1+m2+⋯+mk
其中,
0
<
=
m
i
<
=
n
i
.
0<=m_i<=n_i.
0<=mi<=ni.
令
n
=
m
1
+
m
2
+
⋯
+
m
k
n=m_1+m_2+\dots+m_k
n=m1+m2+⋯+mk,那么将右边这一项的表达式改写为:
x
m
1
+
m
2
+
⋯
+
m
k
m
1
!
m
2
!
…
m
k
!
=
n
!
m
1
!
m
2
!
…
m
k
!
x
n
n
!
\frac{x^{m_1+m_2+\dots+m_k}}{m_1!m_2!\dots m_k!}=\frac{n!}{m_1!m_2!\dots m_k!}\frac{x^n}{n!}
m1!m2!…mk!xm1+m2+⋯+mk=m1!m2!…mk!n!n!xn
所以在生成函数展开式中, 第n项的系数就是
∑
n
!
m
1
!
m
2
!
…
m
k
!
\sum\frac{n!}{m_1!m_2!\dots m_k!}
∑m1!m2!…mk!n!
和式遍历所有
m
i
m_i
mi之和为
n
n
n的情况。
对于一组给定的 { m i } \{m_i\} {mi}, n ! m 1 ! m 2 ! … m k ! \frac{n!}{m_1!m_2!\dots m_k!} m1!m2!…mk!n!表示一个多重集合 S S S的 n n n排列个数。这个结论可以用简单的组合思想来证明:不妨先将每个元素都看作与其他元素不同,那么其全排列种数即为 n ! n! n!,但是其中有 k k k组元素是完全一样并不能区分的,他们每一组的个数为 m i m_i mi。如果考虑某一组的情况,这组相同元素的 m i ! m_i! mi!种全排列均摊了所有全排列的个数,为了避免重复,我们只取一组情况,也就是将总数除去 m i ! m_i! mi!即可。对所有的组数都这样考虑就可以得到不重复的 n n n排列个数。
得知了求和项的组合意义后,我们再考虑 h n h_n hn代表的含义。 h n h_n hn是多重集合的 n n n排列个数,更进一步的说也就是所有的 { m i } \{m_i\} {mi}分组情况对应的排列数之和。那么从组合意义上来看, h n h_n hn就是上面我们求得的和式。
至此,上述定理得证!
虽然该结论证明过程中对每个元素的选取办法没有加以限制,但是如果在有选取限制(如只能取偶数个、至少取x个)或者是某些元素的重数为无穷的情况下,该结论仍然成立!
通俗的说,这个结论就可以忽视 x n n ! \frac{x^n}{n!} n!xn自带的常数 1 n ! \frac{1}{n!} n!1的问题,生成函数中指数为 n n n的项就计数了展开式中每组乘积因子的贡献。
当我们拥有了上述结论后,这道题的系数对应问题也就得到了合理的解释。
B
数据好像是弱了点,直接对
1
e
9
+
7
1e9+7
1e9+7进行取余比较就可以AC了。
正确做法是比较多个模数,用Lucas定理加速组合数求解判断过程。
好像也可以用分治 & 高精度
进行无差错的比较,因为上面的办法可以用1 1 p1 * p2 *... * pn + 1
卡掉;但是我不会。
C
画出递归树后就很容易发现规律了,在BST上搜索即可。
坑点
数据范围在
n
<
2
64
n < 2^{64}
n<264,读入的时候如果一个不小心没开unsigned long long
和%llu
就会惨死。esp: %llu
!
此外好像BST搜索写的极丑…