P2396 yyy loves Maths VII

· · 题解

P2396 yyy loves Maths VII

双倍经验。

f_S 表示集合 S 的答案,若 g_S = \sum_{i\in S} a_i 不合法,则 f_S = 0,否则 f_S = \sum_{i\in S} f_{S\backslash i}

直接做的时间复杂度为 \mathcal{O}(2 ^ n n),开 O2 可以通过。我们枚举 i 的时候通过 \mathrm{lowbit}(S) 做到不枚举无用转移,有 \frac 1 2 的常数。

优化:

代码,不开 O2 获得了最优解(749ms),开 O2 又获得了最优解(476ms)。

怎么没有人写 \boldsymbol {3 ^ {n / 2}} 的做法啊?

A(S) 表示集合 Sa_i 之和。

考虑 k = 1,我们发现相当于求 n! - \sum\limits_{A(S) = x} |S|! (n - |S|)!。子集和等于某个值,考虑 MITM,将 a 分成两部分 L, R,求出 f_{i, j} 表示 R 的子集 R_1 的数量,使得 |R_1| = iA(R_1) = j。枚举 L 子集 L_1i = |R_1|,则答案减去 f_{i, x - A(L_1)} (i + |L_1|)!(n - i - |L_1|)!

使用哈希表维护 $k = 1$ 的 $j$ 一维和 $k = 2$ 的 $l, m$ 两维,时间复杂度 $\mathcal{O}(3 ^ {n / 2} n ^ 2)$。[代码](https://codeforces.com/contest/327/submission/176961722)。不开 O2 会 TLE,开 O2 获得了最优解(383ms)。注意 CF 双倍经验 `unodered_map` 会 TLE,用 `gp_hash_table`。