DP

CF1606E

\(f_{i, j}\) 为剩下 \(i\) 个人最大血量为 \(j\),根据 \(j\)\(i - 1\) 的大小关系做两种转移。一种情况直接容斥 \(j^i - (j - 1)^i\),另一种考虑枚举这轮死了 \(k\) 个人转移。

Submission #345696072 - Codeforces

CF1716C

考虑答案形态一定是先蛇形再直线,我们对于分界点的左右两边分别 DP 计算贡献即可。

Submission #345692866 - Codeforces

CF1716D

注意移动次数是根号级别的,于是直接 DP 然后前缀和优化一下即可。

Submission #345703886 - Codeforces

P3574

考虑直接 DP,需要决定子树的顺序,比较一下交换的情况然后按照得出的式子排序即可。

记录详情

CF1748E

发现最靠左的最大值就是大根笛卡尔树上的 lca,于是两棵树笛卡尔树的形态相同,直接笛卡尔树上 DP 即可。

Submission #345763516 - Codeforces

CF1830D

考虑计算减掉的贡献,发现对于一个同色连通块会产生贡献。

于是考虑直接 DP 设 \(f_{i, j, 0/1}\)\(i\) 子树内,\(i\) 所在连通块大小为 \(j\),最少减掉的贡献。

优化状态,由于黑白染色的情况下减掉的贡献上限是 \(2n\),于是第二维是根号级别的,由于有 size 限制于是就对了。

Submission #345825020 - Codeforces

CF1725J

显然只有一个点或一条边把树划分成两段两种可能,直接换根硬维护五条链长度即可。

代码不想写。

CF1798F

EGZ 定理:对于任意 \(2n - 1\) 个整数,总可以从中选出 \(n\) 个整数使它们的和为 \(n\) 的倍数。

考虑将 \(s\) 从小到大考虑,背包 DP 构造答案。可以使用 bitset 优化到 \(O(\frac{n^3}{w} \times m)\)

https://codeforces.com/problemset/submission/1798/346032506

其实可以拓展到 \(O(n\log n)\),但首先我们得先证明这个定理。我简略写一下。

考虑若 \(n, m\) 成立则 \(nm\) 也一定成立,证明是简单的。

所以我们只需要考虑对质数 \(p\) 证明成立即可。

考虑若众数出现次数 \(\geq p\) 那么显然成立,否则我们一定能分成 \(n - 1\) 个互不相同的点对可一个单独的。我们先选上单独的和点对中的一个点,设当前模 \(n\)\(r\),考虑调整。我们调整相当于让答案在模意义下 \(+x\),其中 \(x\) 为两者的差。

考虑建出一棵树,让 \(0 \sim n - 1\) 为点,所有的 \(x\) 为边。我们的目的是让 \(0 \to i\) 的路径长度模 \(n\)\(i\),这样我们就能构造出模 \(n\)\(r\) 的差值了。

构造时考虑一一加入每个边,即找一个 \(u\) 存在 \(u + x\) 不存在的。如果此时插入不了,说明所有 \(kx \bmod n\) 都在树中,那么一定遍历了所有点,于是构造完了。

考虑我们也按照这个思路去构造答案,难点在于每次找出一个 \(kx \bmod n\) 在树中且 \((k + 1)x \bmod n\) 并不在树中,于是你考虑直接二分一下,维护左端点在树中,右端点不在即可。

CF1767E

限制相当于不能存在两个相邻平台不同色,于是变成最小点覆盖问题。然后就是经典做法,高位暴搜低位记忆化即可。

Submission #346178005 - Codeforces

CF1750F

考虑正难则反,刻画一个不合法的东西。我们钦定左右两段都是 \(1\),对于中间的两个相邻一段 \(l1, l2\) 和零段 \(o\),要求 \(l1 + l2 < o\)。这样有一个非常大的好处是对于一个非法串合并完能合并的后一定存在一个状态下两个相邻 \(1\) 无法合并。我们会发现这种情况下,每个无法合并的态对应的非法串数量等于每个 \(1\) 段对应的合法串个数的积。

\(f_i\) 为长度为 \(i\) 的答案,\(g_{i, j}\) 表示长为 \(i\),以 \(1\) 开头合并完以长度为 \(j\)\(1\) 结尾的不合法方案数。则有 \(f_i = 2^{i - 2} - \sum g_{i, j}\)

想想怎么刻画 \(g\) 的转移,显然如果 \(g_{i, j}\) 要从 \(g_{i', j'}\) 转移过来则必须满足 \(j + j' < (i - j) - (i' + 1) + 1\),即 \(i' + j' < i - 2j\),可以直接前缀和优化。同时还要乘上系数 \(f_j\)

Submission #346756795 - Codeforces

CF1842G

先把期望变成总和除以方案数的形式,于是变成了计数题。

不难发现可以将类似 \(\prod (a_i + v + \cdots)\) 的式子拆开,相当于每个多项式中选一项,对这个东西计数。

\(f_{i, j}\) 表示前缀 \(i\) 钦定了 \(j\) 个操作。那么转移分为当前 \(i\)\(a_i\),或之前就钦定过的 \(v\),或者我们新钦定一个 \(v\)

\(f_{i + 1, j} \leftarrow f_{i, j}(a_{i + 1} + jv)\)\(f_{i + 1, j + 1} \leftarrow f_{i, j}(m - j)(i + 1)v\)

然后计算答案的时候考虑我们一个 \(f_{n, i}\) 还剩下 \(n - i\) 个操作没有钦定,并且这 \(n - i\) 个操作我们没有算它的贡献。

于是答案就是 \(\frac{\sum f_{n, i}n^{m - i}}{n ^ m}\)

Submission #346781781 - Codeforces

CF1120F

会发现如果一直都只有一封信那么贡献就是最开始那封信到终点的距离。所以我们肯定贪心的在连续段的交界处存信,于是可以枚举第一次存信的时间。

Submission #347072246 - Codeforces

CF1707D

挺有意思的。

考虑 DP,想想 lca 封闭是什么,发现其实就是你删一个子树的时候要不然就把根最后删,要不然选择一个子树,先删掉其它子树再删根再删选出的子树。

于是考虑令 \(f(u, k)\) 表示 \(u\) 子树在 \(k\) 时刻删完,转移分为上述两种,有:

\(f(u, k) = \prod_{v \in son(u)}\sum_{i = 1}^kf(v, i) + \sum_{i = 1}^{k - 1}\sum_{v \in son(u)}f(v, k)\prod_{x \in son(u), x \not = v}\sum_{j = 1}^i f(x, j)\)

\(S(u, i) = \sum_{j = 1}^i f(u, j), P(u, i) = \prod_{v \in son(u)} S(v, i)\),则 \(f(u, k) = P(u, k) + \sum_{v \in son(u)}f(v, k)\sum_{i = 1}^{k - 1}\frac{P(u, i)}{S(v, i)}\)

然而直接求逆元会 T,所以维护一个前缀和后缀的积去算即可。

还有一个问题是我们的选择一定要是真子集,所以不能直接算。考虑进行二项式反演,设非真子集时的答案为 \(F(i) = f(1, i)\),真子集时的答案为 \(G(i)\)。显然有 \(F(i) = \sum_{j = 1}^i\binom{i}{j}G(j)\),那么 \(G(i) = \sum_{j = 1}^i(-1)^{i - j}\binom{i}{j}F(j)\)

Submission #347970446 - Codeforces

CF1067D

非常好的 DP 优化题。

考虑如果我们升级后选的一定要是期望最大的。有 \(f_t = \max\{p_i[(t - 1)M + a_i] + (1-p_i)f_{t - 1}\}\),其中 \(M = \max b_ip_i\)

考虑整理一下这个式子,变成 \(f_t - f_{t - 1} = \max\{p_i[(t - 1)M - f_{t - 1}] + p_ia_i \}\)。于是变成了斜率优化的形式,令 \(s_i = (i - 1)M - f_{i - 1}\),那么容易发现 \(s_i\) 是单调递增的。我们将斜率 \(p_i\) 排序就可以维护一个下凸壳 DP 了。

当然这么做显然超时,考虑 \(t\) 很大所以不妨用矩阵优化一下,假设当前最优决策为 \(p_i\),则有:

\[\begin{bmatrix} f_t & t & 1 \end{bmatrix} \times \begin{bmatrix} 1 - p_i & 0 & 0\\ Mp_i & 1 & 0\\ p_ia_i & 1 & 1 \end{bmatrix} = \begin{bmatrix} f_{t+1} & t + 1 & 1 \end{bmatrix}\]

我们可以非常方便地二分出每个决策 \(p_i\) 所对应的最优决策范围,于是就可以 \(O(n\log^2t)\) 了,然而常数太大过不了。

继续优化,我们会发现二分实在是太愚蠢了,考虑将二分替换为倍增。由于我们可以预处理 \(2\) 的次方的转移矩阵,于是可以做到 \(O(n\log t)\)

Submission #348137067 - Codeforces

CF1188D

织体挺简单的。

先排序,然后考虑枚举最大值为 \(v\),那么答案相当于 \(\sum_{i = 1}^n \operatorname{popcount}(x + a_n -a_i)\)

于是我们直接 DP,发现需要考虑进位。观察到第 \(k\) 位进位的数一定是模 \(2^k\) 排序后的一个后缀,于是做完了。

代码太简单了不写了。

CF924F

CF1208H

CF2039F2

posted @ 2025-10-27 20:32  はなこくん  阅读(12)  评论(0)    收藏  举报