ABC349
update on 2024/4/19: F 题的题解写的不太对,正在修。
update on 2024/4/19:修完了
不用考试了/kx/kx/kx/kx/kx/kx/kx
ABCD一眼。
E
发现状态不多,可以直接搜,状态之间的转移关系很容易让人想到 minimax 搜索,直接做即可。注意细节。
F
题面没有废话,数据范围良心,做法巧妙,好评。
一看到 lcm,不难想到要分解质因数,试除法可以通过,不过我们更喜欢 Pollard-Rho。
将 \(M\) 分解质因数为 \(M=p_1^{k_1}p_2^{k_2}\cdots p_w^{k_w}\),一个显然的事情是 \(w\le 13\)。这启发我们放弃多项式复杂度,不过这是后话。
对于 \(A_i\),若 \(A_i|M\) 不成立,则直接扔掉 \(A_i\),这是毋庸置疑的。
接下来对于新的 \(A\),我们状压记录每个 \(A_i\) 在 \(p_j\) 上的信息,显然只需要 \(p_j^{k_j}|A_i\) 的真伪。
题解写的什么神必容斥啊,我怎么看不懂啊。
现在问题等价于,给 \(n\) 个二进制数,问有多少种方案使得选中的数按为或可以得到一个全 \(1\) 的串。
直接做是不好做的,我们考虑容斥。
首先思考一下容斥是什么。
容斥
有很多的集合,我们想求出它们的并集有多少数。
这很明显可以哈希,不过我们想要容斥。
考虑有一张韦恩图。图中的每个圈代表一个集合,若两个圆相交,则代表相交部分为它们的交集。
答案显然就是图上的各部分之和。但没法直接求。我们考虑用计算重合后得到的总数减去重合的部分。
计算重合后得到的总数显然是 \(\sum A_i\)。现在考虑如何计算重合的部分。
直接的思想是减去任两个圆相交的部分,即减去 \(\sum\limits_{i<j} A_i\cap A_j\),但是这样我们又会少算一些东西,因为被三个圆重合的部分被减了两次。还应该加上 \(\sum\limits_{i<j<k} A_i\cap A_j\cap A_k\)。但是被四个圆重合的部分又被多加了一次……
以此类推,令 \(f_s\) 代表被至少 \(s\) 个圆重合时覆盖的部分,易得答案为 \(\sum\limits_{i=1}^n(-1)^{i-1}f_i\)。
虽然正确性在直觉上已经非常对,但是我们还是无法信服。
容易发现 \(ans_k=\sum\limits_{i=1}^k(-1)^{i-1}f_i\) 为在不考虑被多于 \(k\) 个圆覆盖的部分所能得到的答案。由于图中必没有被 \(n+1\) 个圆覆盖的部分,所以只需计算到 \(ans_n\) 即可。
另一种角度来说,我们每次计算被 \(k\) 个圆所覆盖的答案时,所有由 \(k\) 以上的圆覆盖的部分都会被至少计算两次,而不会有 \(n+1\) 个圆覆盖的部分,所以不必往后考虑。
回到这道题。我们考虑记录不合法的方案有多少种。即用容斥的方法,记录对于 \(M\) 的 \(w\) 个质因子,至少一个质因子不被选择的方案数,但是这样会产生重复,所以容斥处理一下即可。
具体而言,对于一个长为 \(w\) 的串,设 \(s\) 是其一个为 \(0\) 的位,我们想让 \(p_s\) 这个质因子不被选择。那么我们能选择的数就是不包含所有的 \(p_s\) 的数。对于这个长为 \(w\) 的串,我们枚举所有为 \(1\) 位组成的集合的子集,只有状压之后在子集中出现过的 \(A_i\) 才是我们能选择的,枚举子集的复杂度上限为 \(2^w\)。
小 trick:对于二进制数 \(S\),我们可以用下面的语句枚举为 \(1\) 的位的子集。
for(int T=S;T;T=(T-1)&S)
这样做的时间复杂度上限是 \(O(2^{w+1}\times\log n)\),总时间复杂度上限为 \(O(\sqrt[4]{n}+2^{w+1}\times\log n)\)。
准确的复杂度分析大概是用子集求和的思路证明。
G

浙公网安备 33010602011771号