@@ -2832,11 +2832,14 @@ func _(abs func(int) int) {
28322832// 给一个全集 U,对 U 的所有子集 S,计算 S 的所有子集 T 之和(这个「和」不一定是加法,可以是其它的满足合并性质的统计量,例如 max 等)
28332833// 特别地,对于计算个数的问题,我们可以对每个子集 S,计算有多少个子集 T 包含于 S(如 CF383E)
28342834// 核心思路:把 S 的所有子集按照最高位是否为 1 分成两组,每组内部再按照次高位是否为 1 分成两组,依此类推
2835+ // 【讲解】https://leetcode.cn/problems/maximum-product-of-two-integers-with-no-common-bits/solution/mo-ban-gao-wei-qian-zhui-he-sos-dppython-78fz/
28352836// 可以看这篇文章里面的图 https://codeforces.com/blog/entry/45223
28362837// 本质理解 https://codeforces.com/blog/entry/72488 Tutorial on Zeta Transform, Mobius Transform and Subset Sum Convolution
28372838// Some SOS DP Insights https://codeforces.com/blog/entry/105247
28382839// 大量习题 https://blog.csdn.net/weixin_38686780/article/details/100109753
28392840//
2841+ // 入门题 https://cses.fi/problemset/task/1654/
2842+ // 高维差分 https://cses.fi/problemset/task/3141/
28402843// LC3670 https://leetcode.cn/problems/maximum-product-of-two-integers-with-no-common-bits/
28412844// 求满足 ai&aj=0 的最大 ai*aj
28422845// LC2732 https://leetcode.cn/problems/find-a-good-subset-of-the-matrix/
@@ -2850,6 +2853,7 @@ func _(abs func(int) int) {
28502853// https://codeforces.com/problemset/problem/1995/D 2300
28512854// https://codeforces.com/problemset/problem/449/D 2400 容斥
28522855// https://codeforces.com/problemset/problem/1523/D 2400
2856+ // https://codeforces.com/problemset/problem/1620/G 2400
28532857// https://codeforces.com/problemset/problem/1679/E 2400
28542858// https://codeforces.com/problemset/problem/1903/D2 2500
28552859// https://codeforces.com/problemset/problem/1208/F 2600
@@ -2868,6 +2872,7 @@ func _(abs func(int) int) {
28682872// - LC3757 https://leetcode.cn/problems/number-of-effective-subsequences/
28692873sosDP := func (a []int ) []int {
28702874// 从子集转移的写法
2875+ // f[S] 表示 a 中是 S 的子集的元素个数,这些元素的 OR 也是 S 的子集
28712876w := bits .Len (uint (slices .Max (a )))
28722877f := make ([]int , 1 << w )
28732878for _ , v := range a {
@@ -2880,12 +2885,32 @@ func _(abs func(int) int) {
28802885}
28812886}
28822887
2888+ // 计算子序列个数(包含空子序列)
2889+ pow2 := make ([]int , len (a )+ 1 )
2890+ pow2 [0 ] = 1
2891+ for i := 1 ; i < len (pow2 ); i ++ {
2892+ pow2 [i ] = pow2 [i - 1 ] * 2 % mod
2893+ }
2894+ for i , fv := range f {
2895+ f [i ] = pow2 [fv ] // 如果要非空子序列,这里额外减一
2896+ }
2897+
2898+ // 高维差分
2899+ // 从 f[s] 中减去 f[s^1<<i],得到 OR 恰好等于 S 的子序列个数
2900+ for i := range w {
2901+ for s := 0 ; s < 1 << w ; s ++ {
2902+ s |= 1 << i
2903+ f [s ] = (f [s ] - f [s ^ 1 << i ] + mod ) % mod
2904+ }
2905+ }
2906+
28832907{
28842908// 从超集转移的写法
2909+ // f[S] 表示 a 中是 S 的超集的元素个数,这些元素的 AND 也是 S 的超集
28852910for i := range w {
2886- for s := 1 << w - 1 ; s >= 0 ; s -- {
2887- s &^ = 1 << i // 优化:快速跳到 i 位是 0 的 s
2888- f [s ] += f [s | 1 << i ]
2911+ for s := 0 ; s < 1 << w ; s ++ {
2912+ s | = 1 << i
2913+ f [s ^ 1 << i ] += f [s ]
28892914}
28902915}
28912916}
@@ -3107,7 +3132,7 @@ func _(abs func(int) int) {
31073132https://codeforces.com/problemset/problem/946/E 2200 重排成回文串
31083133*/
31093134
3110- // 上下界数位 DP(v2.1 模板),计数型
3135+ // 上下界数位 DP · 计数型 (v2.1 模板)
31113136// 比如统计恰好包含 target 个 0 的数字个数,需要区分【前导零】和【数字中的零】,前导零不能计入,而数字中的零需要计入
31123137// 由于 limitLow && i < diffLH 等价于 !isNum,所以 isNum 是多余的
31133138//
@@ -3290,7 +3315,7 @@ func _(abs func(int) int) {
32903315return ans
32913316}
32923317
3293- // 上下界数位 DP(v2.1 模板),价值总和型
3318+ // 上下界数位 DP · 求和型 (v2.1 模板)
32943319// 每个元素 x 有一个对应的价值 f(x),比如 f(x) = x,或者 f(x) = x 中的峰谷个数
32953320// 返回 [low, high] 中的所有元素的价值总和
32963321// https://codeforces.com/problemset/problem/1073/E 2300
0 commit comments