2024.5 做题记录

P1935 [国家集训队] 圈地计划

注意到 相邻两项不同就会产生贡献 的条件不好处理,所以考虑对行列进行黑白染色,将一种颜色格子的 \(a, b\) 交换,这样条件就变成了 相邻两项不同才会产生贡献。然后套用文理分科的做法就可以了。

图论

因为点可以重复经过,所以很自然的缩点然后再对内部含有重要边的 scc 拆点,对于一条重要边必须经过的限制实际就是下界为 \(1\),建出来图然后跑有源汇上下界最小流即可。

关于图的建法,实际上还需要一个虚拟源汇对每个点连 INF 的边。并且这个源汇 不能 直接当作上下界最小流的虚拟源汇,还要再搞一组。(因为实际上第一组是原图为了算答案而构造的,也就是实际上是原图真正需要的点。)

CF1100F Ivan and Burgers

猫树分治,然后做一些线性基合并,复杂度大概是 \(O(n \log n \log V + q \log^2V)\)

不知道暴力线段树维护线性基合并能不能过,能过就太无脑了。

好吃的题目

猫树分治练习题。注意到背包是支持合并的信息,并且容量最大只有 \(200\),分治过程中维护背包即可,查询答案直接合并两边背包即可。

这里的合并不是真的合并,而是枚举一边的容量,复杂度是 \(O(V)\) 的。

[TJOI2018] 数学计算

有点类似线段树分治的想法。注意到一个数贡献的区间是一个连续段,直接打标记维护即可。

二分图 /【模板】线段树分治

每个边的贡献时间是个连续段,线段树分治然后用种类并查集维护二分图即可。

CF432D Prefixes and Suffixes

先求出原串的 Z 函数,然后考虑 即使前缀也是后缀 的限制实际就相当于 \(z[i] = n - i\),其实就是匹配到了字符串的末尾。

然后用 Z 函数能很方便的求出每个前缀的出现次数,考虑对于每个 \(z[i] = k\),其实说明的是 \(i\) 位置可以匹配长度为 \(1, 2, \cdots, k\) 长度的前缀,差分维护每个前缀的次数即可。

CF311E Biologist

不管,以后我要把这些东西统称为文理分科模型了。难搞的地方只有 \(g\),那考虑最小割原本的意义就行,我们想让这条边

  • 如果不割,贡献为 \(w_i\)
  • 如果割了,贡献为 \(-g\)

不妨 \(ans + w_i \to ans\),然后把边权变为 \(w_i + g\),这样割掉之后贡献就是 \(w_i - (w_i + g) = -g\)

BZOJ3252 攻略

带权长剖也没什么区别,剖出来贪前 \(k\) 条就结束了。

[AGC031E] Snuke the Phantom Thief

限制很棘手,因为约束性并不强,我们尝试转化。

枚举当前选了 \(k\) 个点,那么对于 “横坐标小于等于 \(a_i\) 的珠宝最多偷 \(b_i\) 颗。”的限制,我们对于 \(\forall i \in [b_i + 1, k]\),有 \(y_i > a_i\)。其他的三个限制也可以做类似的转化,于是我们对每个点的横纵坐标做出了约束,而我们想满足的条件除了选取的点数需要是 \(k\) 外,还有权值和最大,进而想到费用流。

为了限制每个点只能选择一次,对每个点拆点 \(p, q\) 作为该点的入点和出点,连边 \((p, q, 1, v_i)\) 限制该点最多选一次,且可以获得贡献 \(v_i\)。为了满足 \(x\) 的限制,我们建 \(k\) 个虚点 \(g_i\) 表示当前选择的 \(k\) 个点,同时连边 \((s, g_i, 1, 0)\)。如法炮制另外 \(k\) 个点 \(h_i\) 用来限制 \(y\) 坐标,并且连边 \((h_i, t, 1, 0)\)

考虑对于每组限制连边,例如 \(\forall i \in [b_i + 1, k]\),有 \(y_i > a_i\),那么就可以从 \(i \in [b_i + 1, k]\) 连边 \((g_i, p_j, 1, 0)(y_i > a_j)\),其他几种限制类似。

实现上,可能会出现坐标限制更严格,点数也更严格的情况,所以需要对每一维度维护前缀/后缀的最值。之后跑最大费用最大流即可。

CF1956D Nene and the Mex Operator

考虑到操作次数限制是 \(2^n\) 级别,所以对于一段长度为 \(n\) 的连续段,我们猜测可以在限制内将区间变为 \(n\)\(n\)

直接 dp,令 \(f_i\) 表示前 \(i\) 个数的最大和,有转移

\[f_i = \max(f_{i - 1} + a_i, \max_{j = 1} ^ if_{j - 1} + (i - j + 1)^2) \]

顺便维护转移点,用于构造答案。问题变为给定一段区间,构造方案将区间变为 \(n \times n\),考虑令 \(solve(l, r)\) 表示将区间变为 \(0 \sim r - l\) 的排列,那么对于区间 \([l, r]\) 就有操作方式

  • \(solve(l + 1, r) \to op(l + 1, r) \to solve(l, r - 1)\)

其实意思就是先把 \([l + 1, r]\) 变成 \(0 \sim r - l - 1\),然后再操作一次全变成 \(r - l\),这样就达到了令 \(a_r = r - l\) 的目的,发现余下是子问题,直接 \(solve(l, r - 1)\) 即可解决。

P4103 [HEOI2014] 大工程

先把虚树建出来,然后考虑答案怎么算。

对于第一个,考虑对一条边计算,答案就是 \(\sum w \times sz_u \times (k - sz_u)\),直接算就行。

第二个其实就是在虚树上找树的直径,dp 一下就好了。

第三个其实可以把边取负然后一样是树的直径,但是需要注意一些细节,比如当 \(u\) 为关键点时,此时答案可以直接变成子树内最短路。

注意第二和第三个 dp 当子树内没有关键点时都不能转移。

CF613D Kingdom and its Cities

对于这种 \(\sum k \le n\) 的东西基本都可以先建虚树看看。

考虑这个东西怎么 dp,设 \(f_u\) 表示 \(u\) 子树合法的最小花费,\(g_u\) 表示 \(u\) 子树内是否有 遗留点

首先 \(f_u\) 一定需要保证每个子树内部都是合法的,所以有 \(f_u = \sum_{v \in son_u} f_v\)

然后考虑转移的情况:

posted @ 2024-05-08 18:01  Rainsheep  阅读(403)  评论(0编辑  收藏  举报