「题解」ABC288Ex A Nameless Counting Problem 翻译官方题解 + 生成函数做法

「题解」ABC288Ex A Nameless Counting Problem 翻译官方题解 + 生成函数做法

orz α

dp

翻译官方题解。

考虑 AiAi+1 这个条件可以将序列与可重集构成一组双射。问题就是计算包含 NM 的数的可重集 A 的个数使得 xor 和为 X.而考虑一个值只有出现奇数次才会产生贡献,那么对这个进行计数,再算一下剩下偶数次的贡献即可。

具体地,令 gLLM两两不同的数组成的序列个数使得 xor 和为 X,然后考虑剩余 NL 个数必须是每个值都出现偶数次,那么即有:

ans=i=0N2g(N2i)(N2i)!(M+ii)

这里 g 的定义从可重集修改为序列是因为少了 AiAi+1 这样的限制可能会更容易地计数。

现在有 M,两两不同,xor 和为 X 这三个限制,而 M 和 xor 和为 X 这两个限制都能很好和数位 dp 结合,而两两不同难以在数位 dp 中描述。那就先用数位 dp 求出可以出现相同的方案数,再减去不合法的方案数。前者很容易用 fi,j 表示从高到低考虑到了第 i 位,有 j 个已经脱离了上界的限制,并且前面的位都满足 xor 的限制,方案数是多少。转移的时候枚举有几个新脱离上界的数,这里对于每个 L 可以 O(L2logM) 解决。

减去不合法的情况,先考虑不合法的情况的形态能怎么描述。

这里还是考虑按奇偶分,因为出现偶数次的不会对 xor 产生贡献。为了能够计数还要记奇数和偶数各出现了多少种。所以将不合法的情况划分成这样的等价类:

  • 出现次数为奇数的一共出现了 i 次;
  • 出现次数为奇数的一共有 j 种(j<L);
  • 出现次数为偶数的一共出现了 k 种。

对于每个 (i,j,k) 计算这个等价类的方案数:

  • 选出值的出现次数为奇数的位置,(Li) 种方案;
  • 奇数内部安排位置,要算 i 个元素划分成 j 个大小为奇数的集合方案数 odd(i,j),偶数同理要计算 even(Li,k)
  • 给产生贡献的 j 种数(也就是出现次数为奇数的值)分配取值,有 gj 种方案;给出现次数为偶数的值分配取值,有 (M+1j)k_ 种方案。

那么就是每次要减去:

(Li)odd(i,j)even(Li,k)gj(M+1j)k_

而计算 odd(i,j),even(i,j) 可以提前 O(N3) 预处理出来(枚举最后这个元素所在集合大小)。

而最后这个很容易通过前缀和优化做到每次 O(L2) 统计。

那么总的复杂度就是 O(N3logM)

生成函数

alpha1022 太强大了!

x 为集合幂级数的元,其中乘法是作异或卷积。t 是形式幂级数的元,记录选了多少个数。生成函数直接列出来:

[xXtN]S=0M11txS=[xXtN]S=0M1+txS1t2

先在 x 这一维上做 FWT.

[xT]FWT(F)=S=0M1+(1)|ST|t1t2

再做一下 IFWT.

[xX]IFWT(FWT(F))=12LT=02L1(1)|XT|S=0M1+(1)|ST|t1t2

然后提取 [tN]

再往后一步真是神之一眼!α:这个老典了/shui

结论是 S=0M(1+(1)|ST|t) 只有本质不同 O(L) 个。也就是 S=0M[2|ST|] 只有本质不同的 O(L) 种,

首先考虑 M=2L1 的情况,当且仅当 T 的最后 L 位都为 0 的时候求和为 2L1,如果有一个 1 出现就为 2L1.易证。

然后考虑将所有的 S 挂在 Trie 树上,这样被划分成了 O(L) 棵子树,M 每次有一个 1 就会往左分出去一个子树。然后考虑一个 T 怎样计算答案,发现 lowbit 那一位之上(不含)的那些子树贡献一定为 2d1d 是这个子树的深度为多少,T 的后 d 位出现了 1,而不管上面 Ld 位贡献多少只不过是 [2|ST|]|2|ST|| 的区别,答案都是 2d1.然后考虑 lowbit 那一位及以下的那些子树,它们贡献 0 还是 2d 就取决于 |TM| 的奇偶性了。

所以只需要知道 T 的 lowbit 在哪里,T 的 lowbit 是否在 M 中,以及 |TM| 的奇偶性即可算出 S=0M[2|ST|] 的值。计算这样的 T 有多少个也是简单的。

最后的问题就是有 O(L)ci,计算:

[tN](1+t)ci(1t)M+1ci(1t2)M+1=[tN](1+t)a(1t)b

直接枚举左边 ti 和右边 tNi 然后组合数乘起来就行。

qycnb!d-finite,存在整式递推。令 F(t)=(1+t)a(1t)bF(t)=aF(t)(1+t)+bF(t)(1t),通分之后提取 [tN] 得到整式递推。这样能求出所有的系数,然后就可以对所有的 N 都算出来答案了!!!对 d-finite 还是不熟/fn/fn/fn

时间复杂度就是 O(NlogM)

posted @   do_while_true  阅读(567)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
历史上的今天:
2022-02-12 「题解」LOJ #6499. 「雅礼集训 2018 Day2」颜色

This blog has running: 1845 days 1 hours 33 minutes 52 seconds

点击右上角即可分享
微信分享提示