子序列权值和问题
子序列权值和问题
一、按贡献维度分类的技巧
技巧 1:单元素贡献法
适用信号:权值可写成
如元素和、长度和、平方和、某些标记和。
核心:元素 \(a_i\) 被多少个子序列包含。若没有额外限制:
所以所有子序列元素和:
注意:
- 非空子序列要减去空集贡献;
- 若要求固定长度、必须包含某类元素、至少选 \(k\) 个,则包含次数要重新算;
- 位置不同算不同子序列,这个公式才成立;若要求“不同值子序列”则要另做去重 DP。
技巧 2:点对贡献法
适用信号:权值可写成
如逆序对数、点对距离、乘积交叉项、偏序关系数。
核心:枚举点对 \(i<j\),算它们同时被选中的子序列数:
再乘 \(f(a_i,a_j)\)。
优化:
- 逆序对常用树状数组按值统计;
- 若贡献依赖大小关系,先排序确定偏序;
- 维护数量、和、平方和等。
注意:
- 点对是否有序;
- 是否只算 \(i<j\);
- 重复值是否产生贡献。
技巧 3:极值枚举法
适用信号:权值涉及最大值、最小值、\(\max-\min\)、次大值、前 \(k\) 大。
核心:排序后枚举“谁作为极值”,统计可选元素个数,乘组合数。
例如排序后所有子序列的 \(\max-\min\):
可用前缀和优化。
注意:
- 子序列极值通常排序 + 组合数;
- 子数组极值通常单调栈 + \(DP\),不要混;
- 相同值要规定唯一极值边界,避免重复计数。
技巧 4:阈值拆分 / 层级贡献法
适用信号:出现 MEX、\(\min\)、前缀最小值之和、“至少 \(k\) 个”、覆盖层数、得分至少 \(x\)。
核心:把整数权值写成层级布尔条件之和:
对 \(\min\):
固定 \(k\) 后,条件常变成“每个值至少选 \(k\) 个”这种独立条件,再用组合数 + 前缀积统计。
组合公式:值 \(x\) 出现 \(c\) 次,至少选 \(k\) 个:
CF2030E 的定位:
先发现单数组得分:
再阈值拆分:
固定 \(k,i\) 后,对 \(j\le i\) 每个值至少选 \(k\) 个,值 \(>i\) 随便选,于是:
用前缀积扫。
复杂度关键:
其中 \(p_k\) 是第一个出现次数 \(<k\) 的值位置。所以枚举所有有效 \((k,i)\) 总次数是 \(O(n)\)。
注意:
- 先求单实例公式,再拆层;
- 固定阈值后要检查各值是否独立;
- 非空、模数、组合预处理。
技巧 5:按位拆贡献
适用信号:按位与、按位或、异或和、二进制权值。
核心:按位独立统计:
常见:
- 按位或:该位为 1 的方案数 = 总方案数 - 只选该位为 0 的元素的方案数;
- 按位与:该位为 1 当且仅当只选该位为 1 的元素;
- 异或和:该位为 1 需要选奇数个该位为 1 的元素,若该位有 1,则方案数常为 \(2^{n-1}\)。
注意:
- 空子序列是否计入;
- 非空子序列要单独减;
- 异或最大值问题常用线性基,不是简单按位拆。
技巧 6:DP 维护状态摘要
适用信号:权值不能简单拆,但加入一个元素后状态可用少量摘要更新。
常见状态:
- \(dp[i]\):前 \(i\) 个元素的答案;
- \(dp[i][j]\):选 \(j\) 个;
- \(dp[g]\):gcd 为 \(g\) 的方案数/权值和;
- \(dp[mask]\):按位状态;
- \(dp[max][min]\):值域小时;
- \(dp[0/1]\):是否已选、是否满足条件。
典型:gcd 子序列
不同 gcd 个数只有 \(O(\log V)\) 种,用 map 维护:
同时维护方案数和权值和。
注意:
- 状态是否快速收敛;
- 是否要同时维护方案数和权值和;
- 滚动数组与清空。
技巧 7:增量合并法
适用信号:权值能由“方案数 + 总和 + 必要辅助量”更新。
设当前所有子序列方案数为 \(C\),权值和为 \(S\)。加入 \(x\) 后:
- 不选 \(x\):保留旧贡献;
- 选 \(x\):旧子序列都追加 \(x\)。
若权值是元素和,则需维护方案数和总和;若含平方和、长度、乘积,还要维护平方和、长度和等辅助量。
注意:
- 空集是否在状态中;
- 新单独 \(\{x\}\) 的贡献;
- 权值更新是否非线性。
技巧 8:生成函数 / 多项式
适用信号:固定长度、乘积、组合计数明显。
构造:
其中 \(y\) 记长度,\(x\) 记权值。答案取某些系数和。
实际常用:
- \(O(nk)\) 背包 DP;
- NTT 合并多项式;
- 值域小用背包;
- 只关心长度时 \(y\) 维 DP。
注意:
- 子序列位置不同算不同,生成函数直接乘;
- 若要求不同值子序列,需要去重;
- 模数与 NTT 条件。
技巧 9:容斥与补集
适用信号:求“至少一个满足”“全部满足”“包含某类元素”,正面难算。
常用:
例如:
- 按位或为 0:只选该位全 0 的元素;
- gcd 为 1:总数减 gcd 非 1;
- 必须包含某类元素:总数减完全不选该类。
注意:
- 容斥事件是否独立;
- 空集是否被重复减。
技巧 10:排序 + 数据结构
适用信号:贡献依赖大小关系,如逆序对、偏序、点对距离、极值配对。
流程:
- 排序或离散化确定偏序;
- 枚举一端;
- 用树状数组/线段树维护前面元素的数量、和、平方和。
注意:
- 相同值处理;
- 子序列保序,排序只用于统计偏序,不要改变原位置组合数公式。
技巧 11:前缀积 / 前缀和 / 后缀自由选择
适用信号:固定阈值或状态后,每个位置/值独立,但要求“前缀都满足”。
常见形式:
边扫边维护前缀积。
注意:
- 前缀积为 0 时要小心;
- 后缀自由选择数用 \(2^{n-\sum c_j}\);
- 模逆元是否可用。
技巧 12:枚举有效状态而不是值域
适用信号:看似要枚举很多 \(k,i\) 或 gcd 值,但有效状态总量受限。
常见性质:
- \(\sum p_k\le n\);
- 不同 gcd 只有 \(O(\log V)\) 个;
- 不同前缀最小值只有 \(O(\sqrt n)\) 段;
- 调和级数枚举倍数。
注意:要敢于证明总枚举量,而不是无脑枚举值域。
技巧 13:频数 / 多重集 / 分组统计
适用信号:权值只依赖每个值出现次数,如 MEX、gcd、覆盖层数。
做法:
- 统计 \(cnt[x]\);
- 按值分组;
- 每组内用组合数;
- 组间用前缀积/DP。
注意:
- 值域通常 \(0\le a_i<n\);
- 很多 MEX 题只关心 \(0\) 到第一个缺失值;
- 频数为 0 会截断前缀。
技巧 14:线性基 / 异或子序列
适用信号:子序列最大异或和、异或值数量、异或空间。
常用:
- 线性基求最大异或;
- 异或和之和按位拆;
- 不同异或值计数看线性基秩。
注意:异或和之和与最大异或和是不同题型。
技巧 15:去重子序列
适用信号:题目要求“不同子序列”而不是位置不同。
常用:
- \(dp[i]\) 表示前 \(i\) 个的不同子序列数;
- 用 \(last[x]\) 减去重复;
- 权值和去重更复杂,需按值维护。
注意:大多数“所有子序列”默认位置不同算不同;若题目说“不同子序列”才去重。
技巧 16:空集与非空
通用注意:
- 很多公式先算含空集,最后减空集;
- 空集权值可能为 0,但计数可能影响;
- MEX 空集、gcd 空集、按位或空集要单独定义。
四、题型对照表
| 题型 | 主要技巧 |
|---|---|
| 子序列元素和 | 单元素贡献 |
| 子序列长度和 | 单元素贡献 |
| 子序列平方和 | 单元素贡献 + 平方 |
| 子序列最大值/最小值 | 极值枚举 |
| 子序列 \(\max-\min\) | 排序 + 组合数 |
| 子序列逆序对和 | 点对贡献 + 树状数组 |
| 子序列 gcd 和 | map DP 维护 gcd |
| 子序列按位或/与和 | 按位拆 |
| 子序列异或和之和 | 按位拆 |
| 子序列最大异或和 | 线性基 |
| 固定长度子序列和 | 生成函数/背包 DP |
| 子数组极值和 | 单调栈 + DP |
| MEX / 前缀最小值 / 至少 \(k\) 层 | 阈值拆分 + 组合数 + 前缀积 |
| 不同子序列计数 | 去重 DP + last |
| CF2030E | 先求单数组得分 \(\sum\min cnt\),再阈值拆分,固定 \(k\) 后每值至少选 \(k\) 个,前缀积统计 |

浙公网安备 33010602011771号