#61 CF1927G
题目传送门
观察:每一次操作都可以转化为一次对已覆盖区间的扩展。
因此定义 \(f_{i,j}\) 表示已经考虑了前 \(i\) 个道具的使用情况,并且已经覆盖了 \([1,j]\) 的最小操作次数,第 \(i\) 个道具可以覆盖的范围是 \([L_i,R_i]\),对转移进行讨论:
-
\(i\) 向左染色:\(f_{i,i} \leftarrow f_{i-1,j}+1(L_i-1\le j <i)\);
-
\(i\) 向右染色:\(f_{i,R_i} \leftarrow f_{i-1,j}(i-1\le j<R_i)\);
-
\(i\) 向左染色的同时,\(j(j<i)\) 向右染色:\(f_{i,R_j}\leftarrow f_{j,L_i-1}(R_j>i,L_i\le j)\);
-
回退,显然不会变劣:\(f_{i,j} \leftarrow f_{i,j+1}\);
-
不用 \(i\):\(f_{i,j}\leftarrow f_{i-1,j}\);
时间复杂度为 \(O(n^2)\)。
#62 CF1866I
题目传送门
考虑这个问题没有特殊点的版本应该是什么样的。首先,\((n,m)\) 是必败态,其上方和左侧的点都是必胜态,然后到 \((n-1,m-1)\) 是必败态,以此类推。那么再考虑特殊点,其作用就是把自己改为必败态,然后把上方和左侧的点改为必胜态。
那么可以考虑从 \((n,m)\) 开始递推。进行分类讨论:
-
如果该点下方有特殊点:那么该点及其上方一定是必胜态,向右一步继续判断状态;
-
如果该点右侧有特殊点:那么该点及其左侧一定是必胜态,向上一步进行判断状态;
-
如果该点下方和右侧都没有特殊点:那么该点一定是必败态,其上方和左侧都是必胜态,向右上移动一步继续判断状态;
通过上述分析,该过程至多遍历 \(n+m\) 个状态,又因为每一个关键点只会被询问一次,所以总时间复杂度为 \(O(N+M+K)\).。
#63 CF2126G2
题目传送门
首先,套路地求每一个数作最小值的区间;套路地转化中位数:钦定一个值,将大于它的赋值为 \(1\),小于它的赋值为 \(0\)。
接下来观察要求的值的形式:中位数减最小值。那么随着最小值的增大,如果可能出现答案,中位数至少是应该不降的。
那么可以从小到大枚举每一个元素,判断在当前区间中位数能否增大。时间复杂度 \(O(n\log n)\)。
#64 CF1980G
题目传送门
首先,全局修改转化为对询问的修改。
然后,询问本质就是问以一个点为端点的,异或和最大的路径。可以转化为两条路径的异或和,其中一条路径固定。
接下来就是在一个集合中挑一个值使得其与另一个定值的异或和最大,就是 01 Tire 模板题。
注意:不能选择自己。为了实现这一点,可以通过用可删除 Trie 实现。但是没必要,可以先把询问挂在节点上,然后访问到一个节点时先询问后加点。顺序、逆序各做一次即可。
#65 CF1310D
随机化算法:
首先,没有奇环一般要进行染色。然后就得到一个二分图。定义 \(f_{i,k}\) 表示在 \(i\) 号点已经走了 \(k\) 步的,且每一步只能走到与当前元素不同的点上的最小代价,转移直接枚举即可。单次时间复杂度为 \(O(n^2k)\)。
考虑染色的正确性,对于一个长度为 \(k\) 的边序列,其不合法的情况有 \(2^k-2\) 种,错误率为 \(\dfrac{2^k-2}{2^k}\)。那么在随机 \(7000\) 次后,错误率已经下降到 \(10^{-6}\),可以接受。
确定性算法:
考虑一个访问点的序列 \(p\)。那么没有奇环也就是要求 \(p\) 中奇数位上的每一个元素都不同于偶数位上的每一个元素。那么可以钦定 \(p\) 中奇数位上的元素,然后对于相邻的奇数位 \((u,v)\),找 \(dis(u,w)+dis(w,v)\) 最小且不在钦定的奇数位中的点 \(w\) 作为它们之间的偶数位元素。这一过程可以通过预处理 \((u,v)\) 的上述表达式的前 \(k+1\) 小的 \(w\),然后找到第一个没有出现的 \(w\) 即可。预处理时间复杂度为 \(O(n^3k)\),计数的时间复杂度为 \(O(2^{k/2-1}k)\)。
#66 CF717H
题目传送门
数据范围这么大,感觉很不可做。
但是看到仇恨值只要求大于 \(\dfrac{e}{2}\),这其实非常宽松。考虑随机化。
先跳过队伍这一限制,直接考虑把所有人分到两个联盟中怎么让仇恨值大于 \(\dfrac{e}{2}\)。这是简单的,每判断到一个人,就加入到他讨厌的人较少的那一边,这样至少可以保证有一半的仇恨关系是生效的。
然后考虑选队伍。直接让每一个队伍随机选择一个联盟。如果一个人没有同联盟的队伍可以选,这种情况的概率是 \(\dfrac{1}{2^{16}}\),对所有人就是 \(\dfrac{50000}{2^{16}} \approx0.76\),也就是成功的概率只有约 \(24\%\)。
但是这无伤大雅,直接多随机几次即可。
#67 CF444D
题目传送门
记 \(|s|=n\)。
注意到询问串长不超过 \(4\),说明只需要关心原串中长度不超过 \(4\) 的子串即可。
那么有一个 naive 的想法:找出两个询问串的所有 endpos,分别排序后,钦定先后顺序,双指针求答案。
但是这最坏情况下是 \(O(n)\) 单次询问的。
但是观察到所有长度不超过 \(4\) 的子串总数不超过 \(4n\) 个,也就是说出现次数超过 \(2\sqrt n\) 的串不超过 \(2\sqrt n\) 个。考虑以此进行根号分治:
- 如果出现次数小于 \(2\sqrt n\):暴力进行上述操作;
- 如果出现次数大于 \(2\sqrt n\):预处理其和其他子串的答案;
时间复杂度为 \(O(n\sqrt n)\)。
#68 CF2109E
题目传送门
对前缀操作,那么就从后往前考虑。但是在此之前,要先考虑操作之间能否互换。以 \(s_i=0\) 为例,由于异或操作的特殊性,在 \(i\) 位置和 \(i\) 位置后的操作序列中的第奇数次操作,和 \(i\) 位置上的任意操作互换都是可以的。
这样就可以 dp 了,定义 \(f_{i,j}\) 表示在 \(i\) 位置已经操作了 \(j\) 次的方案数。枚举在 \(i\) 位置进行的操作次数 \(l\),转移要分类讨论:
-
\(f_{i-1,j+l} \leftarrow f_{i,j} \times\large\binom{\lceil \frac{j+l}{2}\rceil}{l}\normalsize(s_i=0)\):根据上述分析,\(i\) 的操作可以放在现操作序列的任意奇数位置;
-
\(f_{i-1,j+l} \leftarrow f_{i,j} \times\large\binom{\lfloor \frac{j+l}{2}\rfloor}{l}\normalsize(s_i=1)\):根据上述分析,\(i\) 的操作可以放在现操作序列的任意偶数位置;
时间复杂度为 \(O(nk^2)\)。
#69 CF1131E
题目传送门
首先,预处理每一个字符串自己的答案是简单的。
然后,考虑一次操作的本质:就是把字符串的前缀和后缀用一个字符连接,重复若干次。因此考虑简化信息,对于一个字符串,维护其长度,前缀最长相同段长度,第一个字符,后缀最长相同段长度,最后一个字符。对操作时的情况进行分类讨论:
-
如果 \(t\) 的第一个字符和最后一个字符不同:那就判断当前插入的 \(s_i\) 和它们是否相同,相同就判断能否更新答案;
-
如果 \(t\) 的第一个字符,\(s_i\)和最后一个字符都相同,且 \(t\) 中有多种个字符:用它们长度的和更新答案:
-
如果 \(t\) 的第一个字符,\(s_i\)和最后一个字符都相同,且 \(t\) 中只有一种字符:维护当前相同段长度,边维护边更新答案;
时间复杂度为 \(O(\sum |p_i|)\)。
#70 CF983E
题目传送门
Observation I:存在一个最优搭乘方案,使得只经过询问两点之间的简单路径。
这启发我们可以像做平凡路径问题一样:先向上跳,在 LCA 处单独处理。那么显然可以用类似树剖的东西维护每一个点可以通过一条线路达到的深度最小的点。这是可以倍增的。
然后考虑回答询问。此时需要一个分类讨论:
-
如果两个询问点有祖孙关系,那么直接询问那么就从深度大的点跳到差一步到深度小的点的位置,然后跳的次数加一就是答案。
-
如果没有,那么就都跳到差一步到 \(LCA\) 的位置,这时候(如果有解)一定存在通过跳两步到对方的方法(即两个人都向上跳一步);也可能存在只需要跳一次就可以的方法(存在一条从一个点子树开始,再另一个子树结束的路径)。那么此时就将 dfn 区间记录下来,之后做一次扫描线即可。
时间复杂度 \(O(n\log^2 n)\)。