牛客挑战赛37 (A-C)

牛客挑战赛37

题解


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+ex
黑球白球取 x + x 3 3 ! + … x+\frac{x^3}{3!}+\dots x+3!x3+,该级数可以写为 e x − e − x 2 \frac{e^x-e^{-x}}{2} 2exex

所以最终只需要求 ( 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+ex)2(2exex)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=(1x21)2(1x2x)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=0hii!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 \} {n1a1,n2a2,,nkak},其中 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=0nii!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!xm2mk!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搜索写的极丑…

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
牛客 a卷2022年第四季度的华为题目中,要求考生设计一种高效的数据结构,能够支持以下几种操作: 1. 添加一个元素 2. 删除一个元素 3. 查找是否存在某个元素 4. 返回元素的总数 该数据结构要求满足空间复杂度较小、时间复杂度较低、能够快速地进行查找和修改等多种操作。 想要编写这样一种数据结构,我们可以参考许多已有的经典算法与数据结构,如二叉树、哈希表、红黑树等,通过综合利用它们的优点来实现这个问题的解决。 例如,我们可以通过哈希表来存储所有元素的值,并在每个哈希链表的元素中再使用红黑树来进行排序与查找。这样,我们既能够轻松地进行元素的添加和删除操作,也能够在查找较大数据范围和数量时保持较高的速度与效率。同时,由于使用了多个数据结构来协同完成这个问题,我们也能够在空间复杂度上适度地进行优化。 当然,在具体设计这个数据结构的过程中,我们还需要考虑一些实践中的细节问题,例如如何避免哈希冲突、如何处理数据丢失与被删除元素所占用的空间等问题,这都需要相应的算法与流程来进行处理。 总体来看,设计这种支持多种操作的高效数据结构,需要我们具备丰富的算法知识和编程实践能力,同时需要我们在具体处理问题时能够将多种算法和数据结构进行有效地结合。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值