1
AGC034 D - Manhattan Max Matching
可以发现曼哈顿距离 \(|x_1 - x_2| + |y_1 - y_2| = max(x_1 - x_2 + y_1 - y-2, x_1 - x_2 - y_1 + y_2, -x_1 + x_2 + y_1 - y_2, -x_1 + x_2 - y_1 + y_2)\),
也就是合法即最大.
所以可以建四个点分别对应四种选择方案, 然后分别与红蓝点两边, 最大费用最大流即可.
3255.【GDOI三校联考】字串转换
考虑把所有字符都归位, 花费为 mincost, 那么之后每个字符都必须是"转圈", 所以可操作总数就是 归位所需操作数 + \(\lfloor \frac{maxcost - mincost}{c[1] + c[2] + c[3]} \rfloor\).
知道可操作总数后, 暴力的做法是设 \(f[x][y][z]\) 表示有 x 位已归位, 有 y 位还差一步, 有 z 位还差两步, 转移显然.
发现 \(n = x + y + z\), 所以可以压成二维, 状态数很小, 矩阵乘法优化即可.
注意不一定要花光总费用, 所以需要多开一位存答案.
CF568 E. Longest Increasing Subsequence
正常的最长上升子序列设 \(d[i]\) 表示长度为 i 的上升子序列的结尾, \(O(n log n)\) 做就好
对于 \(-1\) , 枚举所有待选数更新 \(d\) , 可以先把待选数排序, 这样子两个序列就都具有单调性, 双指针更新就好
考虑构造方案, 对于有值的位置, 记录这个位置的值 \(a[i]\) 和以这个位置结尾的最长上升子序列的长度 \(len[i]\)
从后往前构造最长上升子序列, 记构造到第 \(i\) 位 :
1.如果有有值的位置 \(j\) 满足 \(j < i\) 且 \(a[j] < a[i]\) 且 \(len[j] = len[i] - 1\), 那么就转移到 \(j\)
2.否则找到下一个 \(-1\), 填入最大的合法的待选数并转移到这一位
可以发现每个有值的位置都只会被用一遍, 且如果第一次需要用时它不合法, 那么之后也不会再合法了, 所以可以用链表之类的维护待用的有值位置
以及在开头结尾加极大极小值以避免某些细节。
Nowcoder 13249黑白树
\(nowcoder\) 上给了树形 \(dp\) 的壳但实际上是贪心的一道题。
首先考虑一种显然错误的贪心方法:从叶子节点往上染色,遇到白点就将其染黑,并往上染 \(k\) 个点。
观察一种一条链的情况,\(k = \text{{1, 1, 3, 2}}\),错误贪心会先染 \(3\), \(4\),但是先染 \(3\) 再染 \(4\) 更优。由此可以得出正确的贪心的方法:
依然是从下往上,(长句警告!),每次遇到白点时我们考虑能否通过调整顺序使得先染其子树中的某一点以往上染尽可能多的点(显然我们并不会真正地模拟这一过程,只是这样形象地理解),简单地说,就是每次用 \(k_u - 1\) 更新 \(k_{fa_u}\)。
TJOI2017 城市
没有实现仅为口糊警告
显然的是,需要修改的边一定在原树的直径上。\(n\) 只有 \(5e3\) 不是明摆着让我 \(O(n^2)\) 暴力吗?
直接枚举修改的边,分别 \(dp\) 求出出的两颗子树中 与最远节点距离最近的点 (其实还是直径中点),简单统计答案即可。
[ICPC2015 WF]Evolution in Parallel
将字符串按长度排序,考虑由大到小构造,用队列 \(s1, \ s2\) 分别存储两条路径,及队列 \(t\) 作为中转,设当前构造到字符串 \(c\) :
-
若 \(c\) 同时是 \(s1, \ s2\) 的子串,且 \(c\) 是 \(t\) 的子串,那么将 \(c\) 加入 \(t\),否则将 \(c\) 加入 \(s1\), \(t\) 加入 \(s2\) (这里的 \(s1, \ s2\) 的顺序其实可以调换)。
-
若 \(c\) 只是 \(s1\) 的子串,那么将 \(c\) 加入 \(s1\),把 \(t\) 加入 \(s2\)。
-
若 \(c\) 只是 \(s2\) 的子串,加入顺序与 \(2\) 相反。
-
若 \(c\) 既不是 \(s1\) 的子串也不是 \(s2\) 的子串,此时显然无解。
最后不要忘记清空 \(t\),\(s1, \ s2\) 即为答案。
[NWRRC2013]Correcting Curiosity
考虑枚举 \(A\) 串,可以发现确定 \(A\) 串后,为了答案的合法性,要求 \(A\) 串满足:
- 若 \(A\) 在 \(S1\) 中第一次出现的位置为 \(l\),那么 \(S1[1..l - 1] = S2[1..l - 1]\)。
首先枚举 \(|A|\),再枚举 \(A\) 在 \(S1\) 中 第一次出现的位置 :
知道 \(|A|\) 后,可以 \(O(n)\) 预处理出以任意位置起始的字符串 \(A\) 在 \(S1\) 中出现的所有位置,相当于知道了合法的情况下的 \(B\) 及 \(B\) 在 \(S2\) 中出现的所有位置。
字符串 \(hash\) 可以 \(O(n)\) 比较,总时间复杂度 \(O(n ^ 3)\)。
[NEERC2016]Cactus Construction
指定根后,考虑从下往上构造整棵树,遍历到每个节点,先构造其儿子,再构造自身。
染色当前节点 \(u\) 为 \(3\),儿子 \(v\) 为 \(2\),其余后代为 \(1\)。对于环来说,遍历的过程相当于将环拉成了一条链,染色环中深度最深的点为 \(4\),注意 \(4\) 类点可能指向当前节点或当前节点的父辈,因为我们会在环顶将对应的 \(4\) 类点染成 \(1\),所以不可能指向其子代。
根据 \(v\) 及其子代的染色情况将其 \(v\) 分为三类:
-
a. 儿子 \(v\) 子代中存在 \(4\) 类点且指向 \(u\)。
-
b. 儿子 \(v\) 为 \(4\),此时 \(v\) 势必指向 \(u\) 的父辈。
-
c. 儿子 \(v\) 不为 \(4\) 且子代中不存在指向 \(u\) 的 \(4\) 类点。
考虑连边,首先合并 \(u\) 和 \(a\) 类儿子(此处指 \(j\) 操作),连边 \(3, \ 4\) (环顶 \(u\) 和环底),连边后将 \(4\) 染为 \(1\);
接着合并 \(u\) 和 \(b\),连边 \(3, \ 4\) (\(u\) 与其儿子),注意这里保持 \(4\) 类点不变;
最后合并 \(u, \ c\),连边 \(3, \ 2\),需要注意的是这里连边的其实包括 \(a\) 类儿子,连边后将 \(2\) 染为 \(1\)。
最后将 \(u\) 染为 \(2\) (如果 \(u\) 是环顶的话就染为 \(4\))。
环顶的指向很好判断。
时间复杂度 \(O(n)\) 。
[NEERC2015]Distance on Triangulation
考虑分治,每次枚举一条边 \((u, v)\) 尽可能平均地将多边形分成两半,分别以 \(u, \ v\) 为原点做一遍最短路,可以处理出所有跨过 \((u, v)\) 及包括 \(u, \ v\) 的询问。
边界条件 \(n = 3\),此时直接判一判就好。
[CERC2014]Outer space invaders
首先可以将 \(l, r\) 离散化,这样子 \(l, r\) 就是 \(O(n)\) 级别的了。
考虑区间 \(dp\),设 \(f_{ \ l, \ r}\) 表示消灭在区间 \([l, \ r]\) 中的外星人 (注意要被 \([l, \ r]\) 完全包含)。
每次找到 \([l, \ r]\) 中距离最远的外星人,钦定消灭这个外星人,枚举在哪个时间发动攻击即可,转移简单,时间复杂度 \(O(n ^ 3)\)。