1月省选联考做题记录

news/2025/1/18 17:43:31/文章来源:https://www.cnblogs.com/NianFeng/p/18678652

CF1434E A Convex Game

tag:DP,交换值域,博弈论,凸性。

首先,由于每组数是分开考虑的,题目可以看作一个组合游戏,也就是说我们可以分开考虑每个游戏的 SG 值。对于每一组游戏,套路地考虑构建一个有向图模型。注意到每一步的选择与差是有关的,考虑记录 \(f_{i, j}\) 为,现在 \(b\) 数组的最后两位为 \(a_{i}, a_{j}\),SG 值是多少。转移是好写的,\(f_{i, j} = \text{mex} \{f_{j, k} \mid a_{k} - a_{j} > a_{j} - a_{i}\),需要倒过来考虑。显然,时间复杂度为 \(\mathcal{O}(n^{2})\)。(记游戏组数为 \(T\)。)

考虑发掘性质。下凸是个容忽视的条件,这提示我们差分数组在最坏情况下为 \(1, 2, 3, \dots\)。那么考虑转移最长链,有 \(len = \mathcal{O}(\sqrt{V})\),也就是 \(f\) 数组现在所记的值分布在 \([0, \sqrt{V}]\) 中。于是转换值域,记 \(g_{i, j}\)\(b\) 数组倒数第二位为 \(a_{i}\),SG 值取 \(j\) 时的合法末尾集合,形式化的,\(g_{i, j} = \{x \mid f_{i, x} = j\}\)。但是这个没有解决信息过多的问题。注意到在固定倒数第二位和 SG 值之后,下一位选得越远,上一位可转移的位置更多,而且是包含关系,因此不妨记 \(g_{i, j} = \max \{x \mid f_{i, x} = j\}\),这样信息量就降下来了。

在此基础上,重写一下 \(f_{i, j}\) 的转移:\(f_{i, j} = \text{mex} \{x \mid a_{g_{j, x}} - a_{j} > a_{j} - a_{i}\}\)。这个 \(\text{mex}\) 还是十分不好看,进一步转化为 \(f_{i, j} = \min \{x \mid a_{i} \le 2 a_{j} - a_{g_{j, x}}\}\)。发挥人类智慧,反向扩句一下,有 \(f_{i, j} = x\) 满足:

\[\begin{cases} \forall y \in [0, x): a_{i} > 2 a_{j} - a_{g_{j, y}}, \\ a_{i} \le 2 a_{j} - a_{g_{j, x}} \end{cases} \]

不难发现固定 \(j, x\) 后,合法的 \(i\) 在第一个式子里是一段后缀,在第二个式子里是一段前缀。取最严的限制,记 \(h_{i, j} = \min_{k = 0}^{j} \{g_{i, k}\}\),那么合法的 \(i\) 满足 \(a_{i} \in (2 a_{j} - a_{h_{j, x - 1}}, 2 a_{j} - a_{g_{j, x}}]\)

下面考虑在转移中去掉 \(f\)。有了上面的框,显然可以按 \(j\) 从小往大考虑 \(g\),消除掉 \(\min\) 的影响;相应的,从后往前考虑 \(g\),同样可以消掉 \(max\),那么现在的问题转成一个覆盖问题了。

记得手算上界。

P6778 [Ynoi2009] rpdq

tag:根号算法,根号分治,分块。

有莫队二次离线做法,有时间写写学习笔记,先摆一下这个科技的应用范围:

  • 是个莫队题;
  • 加删点的贡献形式有关当前区间(长度);
  • 同时这个影响可用前缀写成差分的形式。

大概可以把 \(\mathcal{O}(n k \sqrt{n})\) 降到 \(\mathcal{O}(n \sqrt{n} + n k)\)\(k\) 为更新贡献的复杂度。此题还有 top cluster 树分块科技做法,同样不做深究。

先拆贡献,\(\sum_{i = l}^{r} \sum_{j = l}^{r} dist(i, j) = \sum_{i = l} ^{r} \sum_{j = l}^{r} dis_{i} + dis_{j} - 2 dis_{lca}\),两个 \(dis\) 的部分化成 \(2 (r - l + 1) \sum_{i = l}^{r} dis_{i}\) 不用管了,重点在于 \(\sum_{i = l}^{r} \sum_{j = l}^{r} dis_{lca}\)

从特殊性质开始考虑。对于 A,容易做到对每个点计算其作为 \(lca\) 的次数,扫儿子前缀和或者某种换根 DP 都是可行的;对于 C,\(\mathcal{O}(n q)\) 只需要在上述做法的基础上转换 \(sz\) 的定义。但这很没必要,毕竟非关键点的答案在询问中是不重要的,先对关键点建立虚树再做就可以可以达到 \(\mathcal{O}(\sum r - l + 1)\),注意消 \(\log\) 依赖于建虚树的 trick。

理一下 C 性质的两种做法,于是现在手头上有了:

  1. 钦定点集 \(S\)\(\mathcal{O}(n)\) 求对于每个 \(i\)\(\sum_{j \in S} dis_{lca}\)
  2. 钦定点集 \(S\)\(\mathcal{O}(\lvert S \rvert)\)\(\sum_{i, j \in {S}} dis_{lca}\)

于是可以尝试上分块了。对编号分块,设块长为 \(B\),可以用做法 1 \(\mathcal{O}(\dfrac{n}{B} n)\) 预处理点集每个块时各个点做 \(lca\) 的贡献,前缀和之后不难处理整块之间和整散之间 \(\mathcal{O}(\dfrac{n}{B})\) 的询问。(二维前缀和可以 \(\mathcal{O}(1)\)?)散块之间则考虑用做法 2,做完了。

剩下的在于常数优化。

QOJ1197 Draw in Straight Lines【数据不全】

tag:图论,网络流,最小割模型。

非常困难的题,要慢慢来。对操作进行人类思考,发现最后的涂色顺序应该是黑色长条、白色长条、单点修改。于是考虑确定什么信息之后计算花费,显然,需要也只需要 \(b/w_{r/c, i, j}\) 这四种值。

下面进行分析。对于点 \((i, j)\),如果 \(b_{r/c, i, j} = w_{r/c, i, j} = 1\),显然不优:

  • 若这两次黑白染色的区间不互相包含,那么由于白色在后面染,可以让黑色少染一截;
  • 若白色包含黑色,直接不染黑就好了;
  • 若黑色包含白色,由于一个格子最多染两次,不难发现被后面染白的格子只可能被这两次操作影响,那么可以直接把染黑的操作断成两截做,中间不染白。都是两次操作,不用在意 \(b\) 的影响。

于是对 \((i, j)\) 的目标颜色进行分讨:

  1. 黑色:\(w_{r/c, i, j} = 0\),且若 \(b_{r/c, i, j} = 0\) 的话需要用 \(c\) 的代价单独染色;
  2. 白色:\(b_{r, i, j} + b_{c, i, j} < 2\),且若 \(b_{r/c, i, j} = 1 \land w_{c/r, i, j} = 0\) 的话也需要单独染色。

但上面这段分析只包括了 \(c\) 的贡献系数。对于 \(a\),显然有 \(a \sum b/w_{r/c, i, j}\) 的贡献;而对于 \(b\),我们钦定一个方向计算开头次数,即 \(b \sum (b/w_{r, i, j} \overline{b/w_{r, i, j - 1}} + b/w_{c, i, j} \overline{b/w_{c, i - 1, j}})\),其中 \(\overline{x}\) 表示 \(x\) 取反,毕竟是 boolean。

然后怎么办呢?发现选或不选是相对的,因此考虑最小割建模,割一条边表示选择对应情况,吃对应贡献。

  • 基础模型:\(a\) 的限制是好搞的,可以建 \((S, b_{r}/w_{c}, a), (b_{c}/w_{r}, T, a)\),交错连边的分法有点讲究;
  • \(b/w\) 不同时选也比较 trivial,可以建 \((b_{r/c}, w_{r/c}, \infty)\) 的边(\(c\) 是建反边)。这个对应 \(b/w\) 的交错连边;
  • 其他限制:对于黑点,容易的,\(w_{r/c}\) 都不选,连 \((w_{r/c}, T, \infty)\);且 \(b_{r/c}\) 都不选的话要 \(c\) 的代价,连 \((b_{r}, b_{c}, c)\)。这个对应 \(r/c\) 的交错连边;/
  • 对于白点,神秘的,\(b_{r} \land b_{c} = 0\) 的限制,要建 \((b_{c}, b_{r}, \infty)\) 的边;\(b_{r/c, i, j} = 1 \land w_{c/r, i, j} = 0\) 的限制,要建 \((w_{c/r}, b_{r/c}, b)\) 的边。

CJ2036 【2025省选模拟十九】在乡村 V

tag:DP,优化状态数。

错误思路

\(f_{i, j}\) 为做完 \([1, i]\) 的工作,用了 \(j\) 个金币的最小时间。是个完全不能优化的奇怪 \(\mathcal{O}(n m)\)

正确思路

第一步应该是个经典的 DP 优化,交换值域,(或者交换定义?)设 \(f_{i, j}\) 为做完 \([1, i]\) 的工作,在 \(j\) 的时候停止的最小金币花费。

看上去更不能做,所以发掘一下性质看能不能优化状态设计。发现 有效的结束时间 就两个:\(k d, k d + x\),也就是卡着极限去转移。因为 复合人类思维的贪心,让帕鲁休息的时间越短越好,也就是让工作时间尽量连续。于是对于 \(f_{i, j}\) 的转移,找到后面第一个 \(t\) 使得连续完成 \([i + 1, t]\) 的工作之后正好在睡觉来转移。转移式就 trivial 了,尝试不使用金币等到第二天,或者使用金币当天截止一边在睡觉之前再给个任务(我勒个带资本家呀)。

但是现在还 无法确定 有效的 \(j\) 的数量,做不到优化。简单的思考一下,如果每次转移只回退一个晚上,那对于 \(i\) 来讲可能的结束时间就真的只有 \(\mathcal{O}(n)\) 个了。正确性有点玄。倘若最后剩下若干金币,怎么分最优呢?感性理解一下就是,前面的分段是最优的,那么把金币分到之前去使得连续短整体平移,代价是比较大的,不如直接分到末尾,从后往前删。

于是考虑枚举一个后缀,把它们强制变成一个连续段扯出来,把剩下的金币全往上面堆,以此统计答案。这就完了。为什么是连续段呢?因为连续段的限制是最紧的,如果有空掉的睡觉时间,显然在减少时间相同的情况下扔金币到晚上代价最小,大概就得证了。

problem:为什么时间可以优化状态数而金币不可以?怎么想到分金币的方法,真的显然吗?

实现细节

  • 注意到 \(t\) 的位置 只与 \(i\) 的位置和 \(j\)\(k d\) 还是 \(k d + x\) 有关,可以预处理;
  • 有效的 \(j\)\(\mathcal{O}(n)\) 个的,但是它的 值域 不是。初步想法是用 \(2 j - 1, 2 j\) 表示 \(j d, j d + x\),同样预处理一下找到 \([1, i]\) 全部连续的下界和 \([1, i]\) 全部不优化的上界。诶,还是会爆,这就只能记录上述上下界为 \([l_{i}, r_{i}]\),转移的时候直接判断是区间内的第几个值了;
  • \(\mathcal{O}(n) \neq n\),实际上应该开到 \(2 n\) 吧。

写起来细节十分痛苦。

POJ2022D Sum of LCS

tag:计数,容斥,枚举。

POJ 有点厉害。考场不知道哪里来的耐心对着假做法调 4 个小时(

错误思路

考虑转换枚举对象,从枚举两个数变成枚举 LCS 来计数。钦定 LCS 在两个数中的两端数字不一样,保证长度,这个容斥一下可以提前数位 DP 计算。注意到 \(len \le 2\) 的 LCS 会算重,因为数字长度可以达到 \(6\),于是对 \(len = 2\) 的直接枚举去重;\(len = 1\) 的考虑在算上面所有东西的时候都减 \(1\),然后 \(res \gets res + n^{2}\) 并去掉所有数字集不交的数对,这个可以用枚举子集做。时间复杂度忘了但是对的。

看上去是个很厉害的做法,怎么假的呢?\(111\) 会把 \(11\) 算两次,大概就是这样。

正确思路

随手记一个 trick:\(x = \sum_{i \ge 1} [i \le x]\)

第一步转化还是对了,但没完全对。枚举一个子串,计算两者都包含这个子串的对,这个是极其好做的,开个 std::map 就没了。容易算重,怎么处理呢?注意到这个子串和 LCS 的关系是 类似集合包含的,那么不妨从容斥角度想想。

观察 需要去重的情况:一、子串与 LCS 包含;二、多个 LCS。主要是第二个比较不好用普通的容斥算,怎么办呢?由于 \(n \le 10^{5}\),对于 同长度子串(第一项,直接容斥),可能的子串集大小最多为 \(2^{6} = 64\),于是往 std::map 里面扔个可重集就完了!

实现细节

  • 子串要进行 std::unique,不然要用二项式之类的东西;
  • \(\sum_{i = 1}^{n} (-1)^{n - i} \dbinom{n}{i} = [n \ge 1]\),于是拆一下式子发现不需要预处理系数。

AGC055F Creative Splitting

tag:计数,建立双射。

懈怠了,有些题没有总结呀。困难的金牌题,稍微记一下部分分。不是,\(\pmod {998244353}\) 那块是什么鬼,给科技的吗?

部分分思路

  1. 10 pts:\(n, k \le 6\),观察到判定一个 \(a_{i}\) 是否合法只需要关心它在当前数列的第几位,于是考虑记录所有数列的长度。状态数 \(\mathcal{O}(k^{n})\),转移 \(\mathcal{O}(k)\),总复杂度玄学;

  2. 30 pts:考虑对上述状态进行优化。还是由于判定 \(a_{i}\) 的合法性不用关心上一位,对于目前长度相同的数列直接合并好了。也就是,状态记录有多少个长度为多少的数组,总状态数是 \(\sum_{i = 0}^{n} \dbinom{n}{n - i} \times (n - i)^{i}\),写个暴力算出来大概是 \(2e6\) 级别。

写的时候可能有点细节。比如对前后缀做一下以满足扣掉每一位的计数,以及状态可能要哈希一下。

正确思路

第一步还是对的。按照原题模拟,充要条件不好找,于是可以想到双射。首先考虑怎么判定一个数列是否合法,往数列里加数 限制是逐渐变严的,故考虑倒过来 贪心构造可行解。可以这样简单的描述构造过程:

设一个长为 \(n\) 的数组 \(c\),表示各个数组的限制,初始 \(c_{i} = k\)。从后往前枚举 \(b_{i}\),找到最小的 \(c_{j} \ge b_{i}\)\(c_{j} \gets c_{j} - 1\)。如果找不到,寄。

然而光有这个 大小关系 是不好计数的。考虑转成对满足某个大小条件的值的 数量 进行操作;具体的,设 \(d_{i} = \sum [c_{j} < i]\),于是构造过程可以直接表示如下:

初始 \(d_{i} = 0\),从后往前枚举 \(b_{i}\),找到第一个大于等于 \(b_{i}\) 的位置 \(p\),使得 \(d_{p} \neq d_{p + 1}\)\(d_{p} \gets d_{p} + 1\)。如果找不到,寄。

看上去没有简化,但是注意到 瓶颈在于 找到 \(p\),从这方面下手。\(d\) 是单调不降的,原本 \(d_{b_{i}}\)\(d_{p}\) 是相同的,于是操作可以简化到 只与 \(b_{i}\) 有关

初始 \(d_{i} = 0\),从后往前枚举 \(b_{i}\),若 \(d_{b_{i}} = n\),寄;否则,\(d_{b_{i}} \gets d_{b_{i}} + 1\),然后对 \(d\) 重新排序。

这就爽了,直接上套路考虑枚举最终序列,然后计数。留作习题吧,还是有点困难的。

实现细节

  • DP 的数组下标从 0 开始,也就是说初始化在 -1。以后能写滚动数组就写滚动数组得了。

CF1842F Tenzing and Tree

tag:树的重心,构造。

PKUWC 回来搞一下专题复健,整理掉当年速通的题。

正确思路

Step 1:考虑 确定了黑点 之后,怎么确定答案。确定一个根,则每条边的贡献为 \(\lvert key_{x} - (k - key_{x}) \rvert = \lvert 2 key_{x} - k \rvert\)。考虑拆掉绝对值,发现这个 两倍相减 的形式很像某个东西,于是人类智慧一下,直接选择根为这几个黑点的 带权重心,式子就可以拆成 \(2 key_{x} - k\) 了。

Step 2:考虑 确定了根 之后,怎么放点会最优。放一个点时,\(ans = n - 1\);放第二个点时,与第一个点中间连的边 \(con \gets con - 1\),而其他点 \(con \gets con + 1\);放第三个点时同理……容易发现,围着根一层层 BFS 式的扩展,是最优的。

Step 3:考虑结合上面那俩玩意儿。如果直觉够强,会注意到 Step 2 的方法是 \(\mathcal{O}(n)\) 的,只不过问题在于 没有根。所以 \(\mathcal{O}(n)\) 钦定一个根计算答案,全部取 \(\max\) 就可以 \(\mathcal{O}(n^{2})\) 的总复杂度解决了。取 \(\max\) 的正确性?注意到如果计算答案时不使用带权重心,可能的结果只有出现负数贡献,这显然不优,并不会影响到取 \(\max\) 后的答案。

由此也可以观察到,树的重心在 有关子树大小的树上最优化问题 中发挥了比较大的作用。

1767F Two Subtrees

tag:根号算法,莫队,众数,dfn 序,dsu on tree。

有点人类智慧,看一下能不能独立再想出来。

正确思路

众数 已经把 莫队 两个字写到脸上了,下面考虑怎么从这上面下手。首先需要确定派平方式,常用的两种序列 欧拉(环游)序和 dfn 序 中,欧拉序适用于 路径统计,而此题又是子树问题,dfn 序明显更有优势,所以在 dfn 上考虑 进行一个队莫的维四。 不行,这个太垃圾了,我们需要一点带有 dfn 序特性的东西。

一个直观的优化是,怎么把两个子树的四个端点,变成 两个端点。考虑子树在 dfn 序上的表现是一段区间,是否可以考虑 将一段区间看作端点 进行莫队呢?这是可以的,不过需要一点手段来 保证复杂度。具体的,分析一下莫队的复杂度来源其实在于 端点的移动,所以我们需要一个优秀的子树区间移动方法。

也就是 dsu on tree 的分配方式。按 dsu on tree 的时间复杂度分析,每一个块内右端点移动总量 \(\mathcal{O}(n \log n)\),左端点则按照块长定,总复杂度大概是打爆四维莫队了。加之 dsu 的小常数,可以快得飞起。

忘记说众数的实现了。朴素的实现可以记录 \(cnt_{x}\) 表示 \(x\) 的出现次数、\(app_{i}\) 表示 \(cnt_{x} = i\) 的个数,由于加减数只会对 \(cnt_{x}, app_{i}\)\(\mathcal{O}(1)\) 的影响,所以可以 \(\mathcal{O}(1)\) 直接维护 \(mx\) 指针。但现在需要对众数取 \(\min\),上述做法只能快速维护众数出现次数,求具体众数还需要 \(\mathcal{O}(n)\) 扫一遍,可以尝试使用小常数 值域分块,或者大常数 std::set。值域分块的话是 \(\mathcal{O}(1) - \mathcal{O}(\sqrt{V})\) 的,也没啥可以优化,本质是不超过 \(\mathcal{O}(\dfrac{n}{B})\) 次的大跳和不超过 \(\mathcal{O}(B)\) 次的小跳,写一下对比吧。(upd:std::set 被打爆了……)

实现细节

  • 如果正确分块,重儿子置前置后应该是没有区别的;
  • 如果用 std::vector 存图,重儿子可以直接 std::swap\(G_{x, 0}\),然而我不用;
  • 发现 std::max<int>(x, y) 可以解决 doubleint 不兼容的问题;
  • 注意块长的计算方法。莫队的时间复杂度是 平衡左右端点 得来的,不失一般性的,设块长 \(B\),有右端点 \(\mathcal{O}(\dfrac{n \log n}{B} n \log n)\),左端点 \(\mathcal{O}(q B)\) 的复杂度,可以平衡出 \(B = \dfrac{n \log n}{\sqrt{q}}\),比较优秀。

P9021 [USACO23JAN] Subtree Activation P

tag:树形 DP,虚点,回路,dsu on tree。

更加人类智慧。

错误思路

由于题目给的条件是 子树覆盖,直觉告诉我们这个是 dsu on tree。然而并不全对,只能说答案上界是 \(\mathcal{O}(n \log n)\),因为当重儿子可选的时候转移数还是不一定相同的。于是尝试从类似 dsu 转移的角度入手优化。

考虑刻画一下问题。只关心两点之间移动的贡献,若子树包含则为 \(\lvert sz_{x} - sz_{y} \rvert\),否则为 \(sz_{x} + sz_{y}\)。那么就是要找到一个经过所有点的回路,使其边权最小。但此时有 两种边权,加之连边 方式自由,还是不好导出做法,需要限定路径形态。

发现第二种边权由于 不同时依赖 \(x, y\),可以看作一个单独的回路开头考虑;剩下的部分则由第一种边来连更优。于是就可以对着欧拉序套路 DP 啦!具体的,回路 的特殊之处在于每个点不管连谁,只要保证度数为 偶数 就一定是对的。所以记 \(f_{x, 0/1}\) 表示点 \(x\) 当前连边 \(\pmod 2\) 时的情况,转移就 trivial 了……吗?

实际上第一种边还是有问题的。发现 两者包含并不代表父子关系,也有可能是祖孙关系,这就难绷了。那么考虑再记一维 \(0/1\) 表示这层关系,转移时由于绝对值可以自动解除,提前计算贡献就完了。

正确思路

还是太菜,倒在了 DP 分析设计的那一步。

做法一:实际上,确实是若干 欧拉环游路径 更优,只不过在刻画的时候漏掉了一步:直接划分是 不能保证闭合 的,需要一点手段强制闭合。由于点的起始位置不定,直接记录是不现实的。于是考虑 建一个虚点,与其连边 \(sz_{x}\),那么问题可以强化为 \(1 \sim n\) 与这个虚点 互相连通且形成一个大的回路,于是剩下的一维用来补上虚点状态就好了。

做法二:先不设计 DP,继续观察由第一种边连成的图有什么性质,再次 强化限制。经过 手模 发现,最优路径一定是一段上行加一段下行,否则断成两条回路是会更优的;在这种情况下,一条回路的贡献反而方便计算,就是两倍最浅点的 \(sz\)。此时一个只有两种状态的 DP 就 done 了,剩下的留给年枫好好想想。

P4886 快递员

tag:点分治,重心,树上二分。

树上二分是自己取的名字,感觉本质确实是这个。第一边做这个思维题感觉很新鲜的一个点分治,再看已是套路,但还是很好玩。

不过有个 \(\mathcal{O}(n \log^{2} n)\) 或更优秀的 \(\mathcal{O}(n \log n)\) 直接维护每个点答案的做法,难点在于换根的计算,不做细讲。然而正解也没多详细。

正确思路

\(\mathcal{O}(n^{2})\) 的暴力大众分是简单的,对每个点 \(\mathcal{O}(n)\) check 一下就没了。

考虑发掘性质,根据草履虫实验得知,每次钦定一个快递站当根算完答案后,把快递站 往当前答案最长链放是可能更优的。然而单次查询还是 \(\mathcal{O}(n)\) 不能优化,还要发掘性质。

不难得知有任意条分居俩子树,或最长链跨过当前点时,不管往哪边跳都不优,所以 每次移动方向固定,可以用 重心分子树小于等于 \(\dfrac{n}{2}\) 的理论加速这个移动过程。于是完了。

实现细节

  • 判断点在路径上显然可以暴力 \(lca\),但有更聪明的方法:对每个子树标记颜色就好了。

P9669 [ICPC2022 Jinan R] DFS Order 2

tag:树形 DP,回滚背包。

艹,好像又有点快了。压一压速度,提一提质量。不行,还是太简单了(

正确思路

还是能比较自然地想到 DP 的。硬要说突破口的话,可以考虑 DFS 与树形 DP 的强关联性,或者概括为 DFS 先处理子树再处理兄弟 的顺序特点。故可以设 \(f_{x, i}\) 表示 \(x\) 在第 \(i\) 位的方案数。

对于 \(x\),需要在 \(f_{fa, i}\) 的基础上加入兄弟得到 \(f_{x, j}\)。于是,我们需要得到兄弟填完子树的方案数,还要算上 \(k! (cnt_{fa} - k - 1)!\) 的贡献(\(k\) 为前置儿子数),即前后乱排的状况。填子树的方案 \(coe_{x}\) 还是好算的,\(coe_{x} = \prod_{y \in son_{x}} coe_{y} \times cnt_{x}!\),直接 DP 就完了。

考虑从 \(x\) 转移到 \(y \in son_{x}\) 的时候,放 \(i\) 个儿子形成 \(j\) 的空间,看着就比较背包,但由于从上往下 DP,需要想个办法扣掉 \(y\) 的贡献。于是可以用 回滚背包 实现,然后就没了。不知道考场能不能想清楚。

是不是把实现细节说完了?

P8935 [JRKSJ R7] 茎

tag:树形 DP。

有点困难?

正确思路

直观感受是先对着茎周围的子树背包一个 \(k - 1\) 然后继续考虑,然而问题在于前后分开考虑,不可,没准一个点就莫名其妙寄了两次。但是可以考虑 倒序模拟剪茎的过程,同时算上前面的贡献。为什么呢?因为发现加点是可以 逐步确定最后留下来的点数,并且计算上先前就有的删除方案,这就很好。

但一个问题是,计算的是操作序列,在从上往下 DP 时,每次只整出一个连续新点,贡献是好算的;倘若中间隔了一些点,怎么计算答案呢?发现似乎没有影响,只是 \(ans\) 变成一个 后缀和 而已,因为删掉的枝节 与先前的操作序列有双射(可以这么说吗),改变的只有后面减茎的方案数罢了,没有过多影响。

注意 \(x\) 处不可以后缀和,因为后缀和的意义是删掉这个点。剩下的细节依旧是自己想。

ARC087F Squirrel Migration

tag:重心,计数,容斥,猜结论。

错误思路

最优化加计数,考虑 猜个上界 构造一下。理想状态下,对于每条边,其内部的点 \(p_{i}\) 全都是外面的,这样保证边的收益最大化。如何构造呢?为了使每个子树 都能被外面的点填充,不出意外地人类智慧一把,钦定 重心 为根,于是每个子树 \(sz \le \dfrac{n}{2} \le n - sz\),往外面撒点就完事了。(虽然应该是式子推重心……)

由于重心的定义,上面那个还是个 充要条件。然后考虑直接计数。双重心是不是 \((\dfrac{n}{2}!)^{2}\) 就完了,那就只用思考单重心的求法了。是否需要容斥?若设不参与重排的 子树 集合为 \(S\),则贡献为 \((-1)^{\lvert S \rvert} \cdot (n - \sum_{i \in S} sz_{i})! \cdot \prod_{i \in S} sz_{i}!\)。这个式子的第二项 不能直接计算,所以设 \(f_{x, i}\) 为考虑到 \(x\) 时钦定了 \(i\) 不参与外界重排的 方案数乘系数,有 \(f_{x, i} = f_{x - 1, i} - f_{x - 1, i - sz_{x}} sz_{x}!\),最后计算 \(ans = \sum (n - i)! \cdot f_{m, i}\)

正确思路

其实只有容斥寄了。每个点还是要单独考虑的,做完了。

CF724F Uniformly Branched Trees

tag:DP,计数,组合,重心。

错误思路

首先考虑 同构 怎么搞。由无根树同构的 trick,一般可以 钦定重心 来搞搞,于是需要分 单重心和双重心 两种情况讨论。先从单重心入手。

先浅浅的设个状态 \(f_{i, j}\)\(i\) 个点,重心上连 \(j\) 条边,剩下都合法的方案数。然而 限制有点死,因为理论上重心外的点也可以向上连边,这就导致不方便计数,需要更多状态。考虑记 \(g_{i, j}\) 为在 \(f_{i, j}\) 的定义上留一个点连 \(d - 1\) 条边的方案数。然而还是很不能写转移式,因为在转移 \(f\) 的时候要 考虑子树大小的合法性。于是在 \(f\) 里再记一维最大子树大小?设个 \(f_{i, j, k}\) 试试:

\[\begin{cases} f_{i, j, k} \gets \sum_{x = 0}^{j} f_{i - x k, j - x, k - 1} \times calc(g'_{k}, x) \\ g_{i, j, k} \gets \sum_{x = 0}^{j} g_{i - x k, j - x, k - 1} \times calc(f'_{k}, x) \\ f'_{i} \gets \sum_{j \le \frac{i}{2}} f_{i, d, j} \\ g'_{i} \gets \sum_{j \le \frac{i}{2}} g_{i, d, j} + f_{i, d - 1, j} \end{cases} \]

其中 \(calc(i, j)\) 表示 \(i\) 个数里选 \(j\) 个构成可重集的数量,在 前缀和意义下 就是 \(j + 1\) 个空位插 \(i - 1\) 个隔板(因为第 \(i\) 个固定在 \(j + 1\) 的位置了),是不复杂的 \(\dbinom{i + j - 1}{i - 1}\)。这个可以预处理,大概 \(\mathcal{O}(n^{2} d)\) 做完了。

还有双重心的情况。双重心在分析时是不复杂的,可以简单看成 两个 \(sz = \dfrac{n}{2}\) 的树拼起来。但就是这个问题,会计重。怎么办捏?

正确思路

菜死了,其实只用一个 \(f_{i, j, k}\)。上述过程中的 限制太死了,导致会有情况没计到。实际上只用考虑树的 最终形态,因为重心的子树限制 只用关心一级儿子的大小,而不管儿子内部是啥妖魔鬼怪,所以最后一步之前的转移不需要考虑子树大小限制,然后完了。

problem:DP 状态太严或太死似乎都会有分讨过多的问题,如何分辨?

实现细节

差点又要写到思路里去了。

  • 注意到 binom 里面,\(i - 1\) 很大而 \(j\) 比较小,故可以将其拆为 \(\dfrac{(i + j - 1)^{\underline{j}}}{j!}\),预处理就只用 \(\mathcal{O}(n^{2})\) 的总复杂度了。

CJ2002【2025省选模拟九】有缘人

tag:DP,长链剖分。

非常好分类讨论题,使我的 DP 式子旋转,爱来自细节。这是一个有关 Destiny 的小聋瞎对拍出奇迹的励志故事。

抽象思路

啥都记一下,太抽象了。首先是题面,两头的 四个枝节 长度一致,而非分别一致,不然后面的 DP 是做不了的。只能说致敬传奇硬做王(

第一眼,点分治;第二眼,不是点分治,因为点分治 会分割连通块,你又不知道 5 个部分哪个跨重心,别想了。

于是考虑进行一个类的分。一定不要漏情况! 顺便说一下 无根树和有根树 的关系——有根树相当于在无根树的基础上 加入限制,或者说 增加信息,那么一些无根树上不好区分的情况,就可以在有根树上区分,方便分讨。根据 \(\infty\) 次的 暴力对拍 可以得到如下情况:

初步想法是,直接按照类别 DP,比如 I. 看成两个点对凑、IV. 看成一个 F 型然后判断上面接法。由于这些状态与 深度强相关(比如需要记录 \(k\) 级儿子数量),考虑用 长链剖分 优化。然而写一写就会发现,不好转移。问题不在长剖,在于 VI. 和 VII. 的情况在分界点是 考虑不到的,以及这么干的话对于 IV. 会出现 长链的答案不能直接继承,需要扫一遍数组,复杂度会炸的情况。

这种情况的根源在哪呢?其实是 代表元 找错了。在有根树 DP 计数上,更为常见的 trick 是 钦定在最高点上计数,因为这样就只需要关心 子树拼接计算答案,符合 DP 获取信息的顺序。因此再从这方面考虑,简化分讨。

经过观察整合,其实就剩了两类:

这就一副很方便计数的样子。由于计数对象的 特点 或者叫 性质 在于四个枝节等长,DP 就可以经典地设为:

  1. \(f_{x, i}\):下接一条长为 \(i\) 的链的方案数,就是 \(i\) 级儿子,转移时长度递增;
  2. \(g_{x, i}\):下接一个人字,枝节长为 \(i\) 的方案数,这里就可以把在 \(x\) 处分岔的情况并上来,免掉分讨,转移时长度固定;
  3. \(h_{x, i}\):下接一个 F,可能出头,还需要接 \(i\) 的长度的一条链的方案数,这个是顶头分岔的情况,转移时长度递减。

对应的转移有:

\[\begin{cases} h_{x, i} \gets h_{y, i + 1} + f_{x, i} g_{y, i} + g_{x, i} f_{y, i - 1} \\ g_{x, i} \gets g_{y, i} + f_{x, i} f_{y, i - 1} \\ f_{x, i} \gets f_{y, i - 1} \\ res \gets g_{x, i} g_{y, i} + f_{x, i} h_{y, i} + h_{x, i} h_{y, i - 1} \end{cases} \]

需要注意顺序和边界,有点恶心。题解写了个「极其美妙」的多项式转移,据说 DP 的本质就是 模拟多项式乘法。有动态 DP 那味儿了。

实现细节

  • 主要是鬼畜的 空间分法,这个需要依赖长剖过程中的 继承方式\(f\) 是规规矩矩的长剖,不用管;\(g\) 由于长度 不变,同一条长链 共享一段 \(len = dep_{top} - d_{top}\) 的空间;\(h\) 这个 B 玩意儿是递减的,需要倒序分空间,同时注意链头的数据仍可以达到 \(len = dep_{top} - d_{top}\) 的情况,所以 \(aux\) 数组需要开两倍空间。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/871322.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

「NOIP2024」 树上查询

update 2024/12/28 题目描述 给定一棵树,每次询问区间 \([l,r]\) 的 \[\max_{l \le l \le r \le r \land r - l + 1 \ge k}\text{dep}_ {\text{LCA*}(l, r)} \]引理证明 先来证两个区间 \(\text{LCA}\) 的引理: 对于 \(\text{LCA} \{ l, l + 1, \dots r\}\) 我们有 \(\text{L…

Flask Web开发实战:入门、进阶与原理解析PDF免费下载

PythonWeb框架Flask开发团队成员撰写,内容全面,从基础知识到进阶实战,再到源码分析,提供完善的Flask学习路径适读人群 :本书适合了解Python基本语法,想要自己动手做网站的编程人员;熟悉Python。想要从事Python Web开发的后端工程师、运维工程师和爬虫工程师;香葱Django…

CMU 15-445 23Fall总结

注:编译、测试之前运行sudo sysctl vm.mmap_rnd_bits=28 BusTubs architecture: 1. Query Processing (查询处理层) 负责将输入的 SQL 查询转化为可执行的物理查询计划。Parser(解析器):将输入的 SQL 字符串解析为抽象语法树 (AST),检查 SQL 语法是否合法。 Binder(绑定器…

从数据到模型,足球预测方法解析

在足球赛事范畴内,比赛结局始终蕴含着诸多不确定性,而这恰恰构成了足球独特的魅力要素。对于广大球迷而言,尝试预测足球比赛的最终结果,向来是一项极具吸引力与挑战性的活动。 近年来,伴随数据科学以及机器学习技术的迅猛发展,足球预测领域发生了深刻变革。这些先进技术为…

传奇三虚拟机服务端-客户端win10可用

论坛转来的,还没有实验架设 传奇3 虚拟机服务端一键架设。。。好吧,三键架设,据说WIN10可玩服务端启动稍微有点步骤,还算简单吧QQ截图20200414142743.jpg (73.53 KB, 下载次数: 0)下载附件2020-4-14 14:41 上传QQ截图20200414142828.jpg (74.73 KB, 下载次数: 0)下载附件20…

THREE.js学习笔记9——Materials

这一小节主要学习材质 材质用于为几何物理模型的每个可见像素添加颜色。 Materials are used to put a color on each visible pixel of the geometries. 决定每个像素颜色的算法是在程序中编写的,称为着色器。 Three.js 具有许多带有预制着色器的内置材料。 Algorithms that …

[HarekazeCTF2019]baby_rop2(read的libc)

一个normal的栈溢出,没有system和binsh,为ret2libc 这里也没有常见的write和puts,所以我们用read泄露libc基址,并使用printf打印read的地址 这里注意printf的第一个参数必须是格式字符串,即Welcome to the Pwn World again(地址为0x0400770,第二个参数设为read_got(got表…

Living-Dream 系列笔记 第93期

最大流 EK & Dinic本文讲解 EK & Dinic 算法。 最大流 最大流的模型:特别注意:这个流量上限不是单次流量不超过它,而是多次的总和不超过它。 EK 显然这个问题是可以使用 dfs 解决的,但是效率低下。 考虑如下的图。我们发现 dfs 有可能走了 \(S \to A \to B \to T\)…

【每日一题】20250118

我是时间唯一的主人。成为自己的时间的主人是一种奢侈。我认为这是人类能够送给自己的最奢侈的东西之一。【每日一题】 1.(16分) \(\hspace{0.6cm}\)如图所示,在以坐标原点 \(O\) 为圆心、半径为 \(R\) 的半圆形区域内,有相互垂直的匀强电场和匀强磁场,磁感应强度为 \(B\),…

思通数科舆情监测系统:精准实现数据监测与实时预警的应用意义

随着信息化社会的深入发展,舆情管理变得愈加复杂,尤其是在社交媒体和网络平台的广泛应用下,信息传播的速度与影响力呈现出指数级增长。如何高效监测和分析这些海量数据,成为各级政府、企业和公共机构亟待解决的问题。思通数科的舆情监测系统,凭借强大的数据监控与分析能力…

中考英语优秀范文-热点话题-传统文化-009 Dragon Boat Festival 端午节

1 写作要求 为弘扬中华传统文化,增强文化自觉,学校将举行一次英语演讲比赛。请以“ ___________Festival”为题,写一篇演讲稿,介绍一个你最喜欢的中国传统节日。 提示问题: What is your favorite traditional festival? Can you say some basic facts about it? How do…

在线json调试工具

在线json格式化工具,无需登录,打开即用 https://json.openai2025.com/