ABC349

update on 2024/4/19: F 题的题解写的不太对,正在修。

update on 2024/4/19:修完了

不用考试了/kx/kx/kx/kx/kx/kx/kx

ABCD一眼。

E

发现状态不多,可以直接搜,状态之间的转移关系很容易让人想到 minimax 搜索,直接做即可。注意细节。

F

题面没有废话,数据范围良心,做法巧妙,好评。

link

一看到 lcm,不难想到要分解质因数,试除法可以通过,不过我们更喜欢 Pollard-Rho。

M 分解质因数为 M=p1k1p2k2pwkw,一个显然的事情是 w13。这启发我们放弃多项式复杂度,不过这是后话。

对于 Ai,若 Ai|M 不成立,则直接扔掉 Ai,这是毋庸置疑的。

接下来对于新的 A,我们状压记录每个 Aipj 上的信息,显然只需要 pjkj|Ai 的真伪。

题解写的什么神必容斥啊,我怎么看不懂啊。

现在问题等价于,给 n 个二进制数,问有多少种方案使得选中的数按为或可以得到一个全 1 的串。

直接做是不好做的,我们考虑容斥。

首先思考一下容斥是什么。

容斥

有很多的集合,我们想求出它们的并集有多少数。

这很明显可以哈希,不过我们想要容斥。

考虑有一张韦恩图。图中的每个圈代表一个集合,若两个圆相交,则代表相交部分为它们的交集。

答案显然就是图上的各部分之和。但没法直接求。我们考虑用计算重合后得到的总数减去重合的部分。

计算重合后得到的总数显然是 Ai。现在考虑如何计算重合的部分。

直接的思想是减去任两个圆相交的部分,即减去 i<jAiAj,但是这样我们又会少算一些东西,因为被三个圆重合的部分被减了两次。还应该加上 i<j<kAiAjAk。但是被四个圆重合的部分又被多加了一次……

以此类推,令 fs 代表被至少 s 个圆重合时覆盖的部分,易得答案为 i=1n(1)i1fi

虽然正确性在直觉上已经非常对,但是我们还是无法信服。

容易发现 ansk=i=1k(1)i1fi 为在不考虑被多于 k 个圆覆盖的部分所能得到的答案。由于图中必没有被 n+1 个圆覆盖的部分,所以只需计算到 ansn 即可。

另一种角度来说,我们每次计算被 k 个圆所覆盖的答案时,所有由 k 以上的圆覆盖的部分都会被至少计算两次,而不会有 n+1 个圆覆盖的部分,所以不必往后考虑。

回到这道题。我们考虑记录不合法的方案有多少种。即用容斥的方法,记录对于 Mw 个质因子,至少一个质因子不被选择的方案数,但是这样会产生重复,所以容斥处理一下即可。

具体而言,对于一个长为 w 的串,设 s 是其一个为 0 的位,我们想让 ps 这个质因子不被选择。那么我们能选择的数就是不包含所有的 ps 的数。对于这个长为 w 的串,我们枚举所有为 1 位组成的集合的子集,只有状压之后在子集中出现过的 Ai 才是我们能选择的,枚举子集的复杂度上限为 2w

小 trick:对于二进制数 S,我们可以用下面的语句枚举为 1 的位的子集。

for(int T=S;T;T=(T-1)&S)

这样做的时间复杂度上限是 O(2w+1×logn),总时间复杂度上限为 O(n4+2w+1×logn)

准确的复杂度分析大概是用子集求和的思路证明。

G

solution

posted @   BYR_KKK  阅读(17)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示