计数相关
类似方法论?
对计数的式子进行操作:
有时候要计数的式子不太好直接做,我们可以对式子进行某些等价变换后再进行计数。
1. 交换求和号
其实是在转化计数对象,比如对于每个 \(S\) 中合法的 \(T\) 求和,可以转化成对于每个合法的 \(T\) 在多少个 \(S\) 中求和。
2. 数域划分
将求和式里的比如最小值,最大值,中位数,绝对值之类,通过值域上的差分搞掉,那么可以按值大小插入来计数。
好处是把数分成了 0 1 两类,且去掉了求和式中难处理的部分。
qmd 讲课时候一点点做出来的,就是考虑绝对值直接记进状态里太浪费了,考虑直接把绝对值拆成中间的值的个数,所以对于每个值求贡献再求和即可,所以值域就变成了 \(0,1\) 然后只关心 \((0,0) (0,1) (1,0) (1,1)\) 的对数,统计出来后矩阵乘法即可,枚举值的时候需要动态维护单点修。
给 qmd 推的题,关键步骤是求最小值的期望,我们考虑差分掉,按值排序后从大到小加入,统计所有只经过加入点的 dfs 路径概率和,加入前和加入后的差值即为最小值为加入值的概率和,值域又变成了 \(0,1\),容易写出 dp 转移,然后有单点修,我们 ddp 维护即可,卡常技巧为矩阵乘法有特殊性,\(3 \times 3\) 矩阵中永远只有 \(4\) 个地方有值,只记录这 \(4\) 个值即可。
GF 集训讲课题,发现求集合的代价的最大值恰好为 \(k\) 的集合数量,还是差分,扫描 \(k\) 求代价 \(\leq k\) 的集合数量,然后发现每个点只关心自己能变成的权值跟 \(S\) 的大小关系,其中 \(S\) 为根修改前的权值,值域成了 \(O(1)\),单点修,于是又是 ddp 直接维护,但是本题线段树合并做法更简单一点,在深搜中,线段树合并做法更复杂些,这两种做法好像一般共存?。
3. 组合意义
常见的有 \(n^m\) 可以看成 \(m\) 个不同的球放入 \(n\) 个不同的箱子的方案数,另外二项式定理的组合意义也比较常见。
极长的颜色连续段长度的平方求和,关键是怎么把它搞掉,考虑组合意义,就是在极长段内放两个不同的球的方案数,即子区间的个数,那我们枚举子区间考虑贡献即可,这样我们就把极长的限制去掉了,剩下的写出来式子 DS 扫描线维护即可。
这个属于典中典吧,但是我找了一会才找到,发现瓶颈在于 \(m\) 很大,但是 \(n\) 很小,考虑组合意义,就是每个点从包含自己的操作中选一个的方案数,我们未被选择的操作不区分,状态记录选择过的数量,直接转移即可。
我之前分享过的题,还是平方的组合意义,把放两个球的情况记进状态里,分延长连续段,新开连续段,放球,不放球转移。
模拟赛题,还是二项式组合意义,对 \(U^V\) 取模的形式很奇怪,而且 \(U,V\) 都很小,肯定要做文章,如果 \(a_u\) 和 \(S\) 有一项是一定是 \(U\) 的倍数,那我们暴力展开,只关心这一项的个数和另一项的乘积,由于项数 \(< V\) 才有意义,所以状态暴力记录项数即可,考虑扩展,现在 \(a_u\) 和 \(S\) 都不是 \(U\) 的倍数,由于 \(a_u\) 有很多种,不太好搞,那我们将 \(S\) 写成 \(kU + r\),枚举 \(r\),给所有的 \(a_i\) 加上 \(r\) 再做之前的那个东西,多记一个连通块大小即可。
4. 拆贡献
实际上也是转化计数对象的一种,将原求和式写成一些独立的中间变量的式子加减的形式,那么可以分别直接计数中间变量的贡献。
常见的有期望计数转化为计数中间状态的出现概率和或者每一步的期望和,点边容斥等。
qmd 讲课题,考虑每个大于 \(K\) 的连通块会且仅会操作一次,所以操作步数的期望可以变成每个大于 \(K\) 的连通块的出现概率和,出现概率就是在操作排列上边界点都先于连通块内点出现,所以状态记录边界点数量和连通块大小即可。
由于是从上往下遍历,关键一步是把期望步数拆开,设 \(f_i\) 为从 \(i\) 第一次走到 \(i+1\) 的期望步数,这个是 可以线性递推的,接下来是处理 \(n\) 条链,比较巧妙的是,我们设 \(g_i\) 为完整走完 \(i\) 条链的期望步数,那么走完下一条链就相当于在长度为 \(2m\) 的链上走完。
模拟赛场切题,先转为对操作排列计数,然后由于每个未结束的删点集合会且仅会操作一步,所以计数未结束的删点集合的出现次数和即可,这个可以直接树上 dp ,由于关注集合大小,所以要多记一维,做树上背包。
去年和 smr 一起做的,发现限制就是每两个叶子的连通块交非空,等价于所有叶子的连通块有交,交肯定是联通块,所以点边容斥,现在要算有多少 \(S\) 使得 \(u\) 能到所有叶子,这个继续容斥掉就能直接算了,但是每次 \(n^2\) ,总时间复杂度 \(n^3\),那我们就定根做,每个点先只考虑子树内的叶子,最后再和子树外的合并,时间复杂度 \(O(n^2)\)。
转化计数对象
一般题目让我们对什么计数我们优先考虑直接对它计数,如果不好做,我们可以考虑转化计数对象。
特别要注意的是,新计数对象与原计数对象要有双射。
1. 构造生成方式
就是构造题目中计数对象的一种生成方式,使得生成方式和原计数对象双射,那我们可以直接计数生成方式。
往往最直接的生成方式会算重,所以我们需要加强条件,使得二者双射。
求剩下球的集合,这个判定有些繁琐,我们考虑数操作球的集合,由于会算重,我们钦定能操作就操作,显然双射,这个的判定就是一堆矩形和的限制,可以直接 dp 。
2. 概率期望计数转排列计数
有时候题目让我们计数每次均匀随机操作,期望多少步无法继续操作,可以转化为对操作排列计数。
感觉见过很多提,但是模拟赛很多,而且都找不到了。
上面放的 s2oj2463 第一步就是这个。
寻找充要条件
比较强力的手段,题目对抽象对象计数,我们把抽象的对象用一些充要的条件表示出来,然后直接对着条件 dp,再寻求别的优化。
模拟赛题,求失败状态数,由于过程极其复杂,你肯定不能直接去刻画模拟过程转移,启发我们寻找判定的充要条件,发现 \(a\) 单峰,\(t\) 单谷,且峰顶和谷底相邻,\(a_i+t_i-1 \leq n\),若 \(t_i<t_{i+1}\),则 \(a_i+1\neq a_i+1\) ,这些条件即为充要条件,直接 dp 发现过程跟 \(n\) 有关不能预处理,启发我们倒着 dp ,跟 \(n\) 无关,可以 \(O(n^3)\) 预处理,每次询问 \(O(1)\) 回答。
虽然是递归结构,但是不能直接 dp ,因为啊,你不知道在哪分隔序列,但是啊,你发现可以从左到右 dp ,记录前缀和,但是 \(n^2\),你把 dp 的限制写出来就是 \(\sum a_i = n-1\),\(\forall _i \sum _{j \leq i} a_j \geq i\),因为你这个过程不就是一棵树吗,这东西反射容斥做完了,话说这东西跟 P12969 中 \(a\) 序列一模一样,这个题也是写出这个充要条件再继续做。
定序:
有时候题目让计数的对象有很多限制,计数是在高效的判定,所以我们可以选择一个判定(计数)的顺序,使得限制条件更好刻画或者处理。
1. 排列计数
计数的对象是排列,常见的排列计数的序有扫描位置按值插入 dp 和扫描值按位置插入 dp 两种。
这东西大家都比较熟悉,连续段 dp 和一些技巧放在这说也跟主题不符合,所以不给题了。
2. 按限制的松紧定序
qmd 讲课时提到了如果一堆限制如 \(b_i\) 从 \(\leq x_i\) 中选若干个出来,那么 \(b\) 序列的数量可以按 \(x_i\) 排序后,从小到大考虑,直接一堆组合数乘起来。
3. 定序使得 dp 无后效性
算是经典题把,关键步骤是因为一张牌只能在一轮中用,所以我们一轮的一轮 dp 有后效性,启发我们所有轮一起做,因为一轮用了一张牌本轮直接结束,所以我们从左往右扫,发现只关心还剩下多少轮,状态多记一维即可,转移是平凡的。
本来定序使得限制更好做的题很多,但是找了找没找到,有了再放把。

浙公网安备 33010602011771号