【FWT 数学 根号分治】 [省选联考 2022] 卡牌
前言
这里是去不了省选的菜狗,只能场外口糊/kk
同时这里的复杂度并不算很正确,只是上界比较宽松,加上数据比较水,所以能过。
先在这里感谢场外和我一起精神进队的大佬 @gzw2005 提供本题的思路
题意
小 A 有 \(n\) 张卡牌,编号为 \(1, 2, \ldots, n\)。每张卡牌上写着一个正整数,第 \(i\) 张卡牌上的正整数为 \(s_i\)。
现在有 \(m\) 轮游戏,第 \(i\) 轮游戏会给出 \(c_i\) 个质数,小 A 需要选择任意多张卡牌,使得这些卡牌上面的正整数的乘积能被该轮游戏给出的每个质数整除。对每轮游戏求出选择卡牌的方案数
【数据范围】
对于 \(100 \%\) 的数据,\(1 \le n \le {10}^6\),\(1 \le s_i \le 2000\),\(1 \le m \le 1500\),\(1 \le c_i, \sum_i c_i \le 18000\),\(2 \le p_{i, j} \le 2000\)。
思路
约定
\(cntprime\) 表示小于值域 \(\omega\) 的质数个数
\(cntprime'\) 表示小于 \(\sqrt{\omega}\) 的质数个数
\(cnt_i\) 表示值为 \(i\) 的卡牌个数
\(\alpha\) 表示大于 \(\sqrt{\omega}\) 的质数个数
\(O(2^{cntprime} \omega)\)
值域 \(\omega \leq 30\) 的分看起来很好混?质数个数只有 \(10\) 个,不妨考虑状压。
设 \(f_i\) 表示 已经满足了哪些质数,此时选取卡牌的方案数。
依次加入值为 \(j\) 的卡牌,转移即为 \(f_k = \sum _{i|j=k} f_i \times (2^{cnt_j}-1)\)。
\(O(2^{cntprime} \omega)\) 预处理,即可 \(O(1)\) 回答询问。
喜提 25 pts!!!
\(O(2^{cntprime'}(\alpha \times m))\)
分析复杂度瓶颈,那个 \(2^{cntprime}\) 的系数太谔谔了!
我们发现大于 \(\sqrt{\omega}\) 的质数的次数在 \([1,\omega]\) 最多为 1。
出现次数太稀疏了!考虑根号分治。
对每个大于 \(\sqrt{\omega}\) 的质数开个桶,对小于根号的质数进行状压。
设 \(f_{i,j}\) 表示只用所有最大质因数为 \(i\) 的数,组成小于根号的质数构成为 \(j\) 的方案数(至少选一个)。
设 \(g_{i,j}\) 表示只用所有最大质因数为 \(i\) 的数,组成小于根号的质数构成为 \(j\) 的方案数(可以不选)。
若没有大于根号的质数,则令 \(i=0\)
可以 \(O(2^{cntprime'} \alpha)\) 进行预处理
答案序列初始为 \(Ans={1,0,...,..0}\)
或卷积定义为:
\(c=a*b,c_k = \sum _{i|j=k} a_ib_j\)
若一个值 \(i\) 在询问序列中 则用 \(Ans\) 和 \(f_i\) 进行或卷积。
反之 \(Ans\) 与 \(g_i\) 进行或卷积。
这里要记得排除掉没选上的贡献。
用 \(FWT\) 可以做到 \(O(2^{cntprime'}(\alpha \times m))\) 处理询问
\(O(3^{cntprime'}\sum c_i + 2^{cntprime'}\alpha)\)
我们做完这个 \(Ans\) 还有大量的信息冗余...太浪费辣!!!
不妨摒弃前文的朴素状压。投入容斥的怀抱吧!!!
设 \(f_{i,j}\) 。其表示只用所有最大质因数为 \(i\) 的数,小于根号的质数构成不与质数集合 \(j\) 相交的卡牌数。
则根据容斥思想,即为