The 4th Universal Cup. Stage 4: Grand Prix of Chengdu(无 EI)
A. A Lot of Paintings
对于给定的 \(x\%\) 实际的范围应当是 \([(x - 0.5)\%, (x + 0.5)\%)\),\(0%\) 和 \(100%\) 会稍微有点特殊。
把所有区间合并起来就可以知道能否构造出 \(100\%\) 了,最后构造成整数只需要把分数乘上分母就行了。
时间复杂度 \(\mathcal{O}(n)\)。
B. Blood Memories
\(n\) 很小,考虑记 \(f_{s, t}\) 表示上一轮选中集合为 \(s\) 当前轮选中集合为 \(t\) 是否合法。
因为 \(R\) 很大,这启发去矩阵快速幂,所以考虑把 \(f_{s, t}\) 改为若合法则值为造成的伤害否则为 \(-\infty\),这样就可以矩阵快速幂了。
时间复杂度 \(\mathcal{O}(8^n\log R)\)。
C. Crossing River
把一个过河过程中间无意义的等待时间都去掉,具体来说,若 \(a\) 时刻到达了某个案但是 \(b > a\) 时刻才离开,那可以直接把 \(a\) 时刻前的步骤都往后平移 \(b - a\) 个时刻,因为是往后调整这不会影响合法性。
于是可以认为过河的过程是在一个岸边等待一段时间后不停留的不断往返直到送完了人。
倒着考虑这个过程,若知道了最后会停到哪个岸边,那么这个岸边的人按时间从后往前至少需要 \(2k, 4k, 6k, \cdots\),另一个岸边的人按时间从后往前至少需要 \(1k, 3k, 5k, \cdots\) 的时间。
并且这个方案是容易构造的,就是不断往返,答案也就是每个点的到达时间 + 到最后需要的时间取 \(\max\)。
最后答案在两个终点中取 \(\min\) 即可。
时间复杂度 \(\mathcal{O}(n\log n + m\log m)\),瓶颈在排序。
D. Deductive Snooker Scoring
当 \(n > 6\) 时一定是剩 \(n - 6\) 个 \(1\) 分球和 \(2\sim 7\) 分球,击打规则是打进一个 \(1\) 分球并且可能打进一个多分球。
当 \(n \le 6\) 时一定是剩分数最高的 \(n\) 个多分球,击打规则是打进剩余的分数最低的球。
于是状态只需要记录 \([n, a, b, p]\),直接转移即可,可以类似 dij 的做法顺便求解方案。
时间复杂度 \(\mathcal{O}(T + SL\log S)\),\(S\) 为状态数 \(200^2\times 21\times 2\),\(L\) 为字符串长度 \(\le 100\)。
F. Following Arrows
厉害题目🤯。
首先考虑一维的情况,此时一个极端的情况是 LLLLLLLx。
虽然手玩一下发现这只有 \(\mathcal{O}(len^2)\) 步,但是会发现很重要的一点是若此时在点 \(p\),点 \(p\) 之前的点状态都是 L。
这说明每个点是 R 和 L 对最终步数的贡献是独立的,是 R 就直接走,是 L 就走过前面的所有 L 绕很多步再回到变成 R 的这个点走过去。
这启发在二维的矩阵上预先构造好一条 \((1, 1)\) 的 \((n, m)\) 的路径,并且满足每个点反向后走到的点依然在路径上且在这个点之前,一个构造是:
RRRRRRRD
DLLLLLLL
DRRRRRRD
DUDLLLLL
DUDRRRRD
DUDUDLLL
DUDUDRRD
RURURUxx
这样构造的原因是这个路径和上面一维的情况类似,走到一个点时已经走过的点一定都是反向的,那么反转每个点对步数的贡献依然是独立的。
记反转一个点 \(i\) 后会走点 \(j\),反转 \(i\) 多出的步数 \(f_i\) 可以 DP 算出:\(f_i = 1 + \sum\limits_{k = j}^i (f_j + 1)\)(注意 \(f_i\) 不包含 \(i\) 向后走的那一步)。
跑个背包会发现 \(\ge 62\) 步的状态都可以构造出来(\(62\) 是因为全正向也需要 \(62\))步,\(< 62\) 步的状态可以用一些小的矩阵构造,可以参考代码实现。
如果跑背包的话复杂度可能有点受不了(应该可以外层先预处理出背包,可能需要 bitset),直接从大到小排序后能减就减就能过。
时间复杂度 \(\mathcal{O}((nm)^2)\)。
G. GCD of Subsets
首先考虑简单一点的 \(k = 1\),此时 \(1\) 可以单独分一组,其余的至少 \(2\) 个一组,发现 \((2, 3), (4, 5), \cdots\) 就行了。
对于修改,如果最后单出了一个数没找到配对,就可以先把这个数改成 \(k\),然后每次把一个对改为 \((k, k)\) 后拆成单独一组答案就能 \(+1\)。
对于任意 \(k\) 是类似的,考虑把数集分为两部分,是 \(k\) 的倍数和不是 \(k\) 的倍数,是 \(k\) 的倍数都除 \(k\) 后就是 \(k = 1\) 的情况,不是 \(k\) 的倍数的部分优先把修改用在这部分一定不劣。
时间复杂度 \(\mathcal{O}(1)\)。
H. Heuristic Knapsack
神题🤯。
对比一下 Alice 和 Bob,发现 Alice 的策略会相对好考虑一些,因为 Alice 选中的一定是个前缀,而 Bob 选中集合的就没有这样的性质。
先考虑重量已经确定的物品,因为选中的是前缀,所以考虑直接枚举选到的物品集合。
对于重量确定且权值未确定的物品,贪心的考虑一定是会被选中的物品价值为 \(10^9\),没被选中的物品价值为 \(1\)。
于是所有物品的权值都确定好了,Bob 选取的顺序就是固定的了。
接下来就只需要给权值确定重量未确定的物品分配重量,玩一下能知道这类物品的作用就是确保没被选的物品不被选。
于是分为两种,被选和不被选,被选会根据当前未分配重量和分界线后没被选的物品重量有个上界,不被选就直接选成 \(10^9\)。
贪心考虑,一定从前往后每个物品重量都顶满上界,如果无法分配则只能不被选。
可能这样构造完还是不满足,所以还需要 check 一下。
因为物品重量上界和总重量上界都是 \(10^9\),所以可能会出现一些小问题。
当就选择一个物品时为了顶满上界会选择重量是 \(10^9\),但钦定一个物品不被选也是 \(10^9\) 的重量,就有可能在 Alice 看来没被选的物品反而排在前面。
但是可以选择的重量上界是 \(10^9\) 可以推出没有选择任何一个确定重量的物品,且确定重量的物品的重量都是 \(10^9\),所以只需要把要选的物品的重量分配为 \(10^9 - 1\) 即可。
时间复杂度 \(\mathcal{O}(n^2\log n)\)。
J. Judging Papers
已经合法的不需要调整,不合法的若还可以调整且调整后合法就调整。
时间复杂度 \(\mathcal{O}(nm)\)。
K. K-Coverage
首先可以前缀和一下得到每个点被覆盖的次数 \(c_i\),然后每个点根据去掉了一条覆盖其的线段或增加了一条覆盖其的线段有对答案的贡献 \(a_i = [c_i = k + 1] - [c_i = k], b_i = [c_i = k - 1] - [c_i = k]\)。
对于增删线段,考虑分讨两个线段的情况:
- 若两个线段无交,则枚举删掉的线段,贡献是可以前缀和后算出的。
新的线段可以是不与当前线段交的任意一条线段,前缀和算出每个长度为 \(L\) 的新线段的贡献后,能选的新线段是一个前缀和一个后缀,做个前后缀 \(\max\) 即可。 - 若两个线段有交,不妨设删去线段左端点为 \(l\),加入线段左端点为 \(l + j(j < L)\),贡献为 \(\sum\limits_{i = 0}^{j - 1} a_{l + i} + \sum\limits_{i = 0}^{j - 1} b_{l + L + i}\)。
于是可以记 \(d_i = a_i + b_{i + L}\),贡献即为 \(\sum\limits_{i = 0}^{j - 1} d_{l + i}\),前缀和后用单调队列维护即可。
还有一种情况是加入线段右端点是 \(r - j(j < L)\),此时记 \(d'_i = a_i + b_{i - L}\) 一样前缀和后单调队列解决。
需要注意的是这个题限制了左端点必须 \(\ge 0\),注意边界情况(不是很懂这样做的意义是什么😅)。
时间复杂度 \(\mathcal{O}(n + L)\)。
L. Label Matching
贪心的,如果有 \(a_i = b_j\) 肯定是能配对则配对。
接下来 \(a, b\) 会各自剩下一些失配的和 \(0\),此时只能失配的和 \(0\) 配对或者 \(00\) 配对。
\(00\) 配对肯定不太优,一定是优先配对失配的和 \(0\),于是合法条件就是 \(0\) 的数量 \(\ge\) 失配的数量。
把 \(a\) 的值带上 \(+1\) 的系数,\(b\) 的值带上 \(-1\) 的系数,求和后的绝对值就是失配的数量。
于是 map 启发式合并即可。
时间复杂度 \(\mathcal{O}(n\log^2 n)\)。
M. Meeting for Meals
好题!!!
首先最早时间就是所有 \(a_i\) 到 \(1\) 的最短路的最大值。
对于陪伴时间,因为两个人碰到后只要能到 \(1\) 就可以一直走,所以只需要算最短相遇时间。
假设 \(x, y\) 在 \((u, v, w)\) 这条边相遇了(\(x\) 过 \(u\),\(y\) 过 \(v\)),那肯定是在时刻 \(\frac{dis_{x, u} + dis_{y, v} + w}{2}\) 相遇的,因为 \(x, y\) 站在一个点等到另一个人来的时间和先在边上相遇再走到点上的时间是相同的。
判定是否能走到 \(1\) 需要分讨一下边上相遇后是走到哪个整点:
- 走到 \(u\),考虑 \(y\) 的路径,需要 \(dis_{y, v} + w + dis_{u, 1}\le t_{\max}\)。
- 走到 \(v\),考虑 \(x\) 的路径,需要 \(dis_{x, u} + w + dis_{v, 1}\le t_{\max}\)。
其实应该还需要满足一个条件是 \(dis_{y, v}\le dis_{u, x} + w, dis_{u, x}\le dis_{y, v} + w\),否则相遇的点其实不在这条边上。
这样的边一定是存在的,考虑以 \(x, y\) 两个点为起点,那么有一部分点是 \(x\) 出发的最短路,一部分点是 \(y\) 出发的最短路,两部分的边就满足以上条件。
且如果不是在这类边上相遇一定是不优的:
- 相遇的时间更长。
- 假设这条边在 \(x\) 的区域,那么过程肯定是 \(y\) 需要更长时间到一个点上然后和 \(x\) 相遇直接到 \(1\),考虑 \(y\) 到 \(1\) 的路径长度,一定是不短于 \(y\) 一进入 \(x\) 的区域就往 \(1\) 走的。
接着考虑固定 \(x\) 但是有多个 \(y\) 的情况,会发现 \(dis_{y, v}\) 肯定是越小越好,相遇时间小也更容易合法,所以以 \(x\) 和所有 \(y\) 为起点跑最短路,只考虑所有 \(x\) 为最短路的点连到 \(x\) 非最短路的点的边即可。
对所有 \(a_i\) 求答案也是一样的,先以所有 \(a_i\) 为起点跑一次最短路,只考虑两端最短路起点不同的边,若合法给两个起点贡献即可。
时间复杂度 \(\mathcal{O}(m\log m)\)。
浙公网安备 33010602011771号