2024.11.12 test
A
一个网格图,你可以任意行走到相邻的格子;可以任意进行发射传送门,可以朝任意方向,传送门会放在第一个碰到的墙壁处。可以删掉传送门,只允许存在两个门,使用传送和走一格花费 \(1\) 的时间。
给定起点终点,问最短时间。
预处理每个点最近的墙,然后先在这个点发射传送门,走到最近的墙这里传送过去即可。
B
\(n\) 堆硬币,每堆硬币的价值形如 \((a_i,b_i,a_i)\),只有拿了上面的硬币才能拿下面的硬币。
问对于每个 \(k\),拿 \(k\) 个硬币的最大价值。\(n\le 5e6\)。
如果一堆只有两个硬币就是 CF436E 反悔贪心,但是你惊人地发现硬币多了复杂度还要少。
考虑找性质。观察到,一堆硬币可以拆开成两个物品,一个是 \(a_i\),一个是 \(a_i+b_i\),他们是独立的。
然后相当于做背包,考虑把大小为 \(1\) 的和大小为 \(2\) 的分别排序,然后做一个双指针之类的即可。
类似 CF808E。
C
字符集大小为 \(k=10\) 的字符串,\(q\) 次询问一个区间本质不同子序列的个数。\(n,q\le 5e5\)。
考虑 dp,不妨设 \(dp_i\) 表示考虑前 \(i\) 个字符的本质不同子序列的个数。
那么考虑最小表示法,设当前的字符是 \(c\),\(dp_i=2dp_{i-1}-dp_{las_{c}-1}\),\(las\) 表示上一次出现。
考虑 ddp,写成矩阵很简单,考虑存 \(dp_i\),以及对于所有 \(c\) 的 \(dp_{las_c-1}\)。
后面就是一个经典题,考虑 P6009,注意到转移矩阵与逆矩阵都是只有 \(O(k)\) 个位置有值,
那么预处理前缀矩阵积,逆矩阵积是复杂度 \(O(k^2)\)。询问的时候是向量乘矩阵也是 \(O(k^2)\)。
注意到我们是向量 * 逆矩阵 * 矩阵的形式,向量只有一个位置有值,最后出来也只有求一个位置。
所以可以递推矩阵积的时候只存一行或一列的值下来,以此卡空间。