seerc2021
A
比较字符串的字典序可以进行贪心,所以用一个指针从前往后扫描,维护一个计数器,对于当前字符,如果两个串相同则可以累加计数器,否则若字典序较小,则统计答案,合法的区间左端点个数为计数器累加的数,右端点个数为右边剩下的数,若字典序较大,则清空计数器,因为以后的都不满足题意。
B
不难发现加的操作可以直接使用可持久化线段树维护,对于区间覆盖来说不太好弄,因为区间覆盖后无法很好的维护列,考虑列实际上很少,以及可持久化线段树具有很好的合并功能,所以对于每种可能的合并情况都使用线段树进行维护,如果区间覆盖就直接在没有这一列的情况下加入即可。
C
容易想到一个看上去时间复杂度很假的做法,枚举颜色,然后做树上背包,实际上用到一个结论,在树上归并时,如果限制子树大小为 ,那么最终的时间复杂度是 ,这样的话最后时间复杂度为 。
下面证明这个结论,有两种方法理解。
方法一,考虑将两个联通块归并时,这两个连通块的大小,第一种,都大于 ,那么归并一次的时间复杂度是 ,归并次数不超过 ,第二种,仅有一个大于 ,那么每归并一次就会少一个小于 的连通块,这样也是 ,第三种,都小于 ,这样可以先合并出若干个大于 的联通块,每个连通块消耗 ,最多 个块。
方法二,归并时强行假设枚举的点对是 dfn 序最接近的 个点,这样点对中两个点的 dfn 序差不超过 ,最后得到的点对是 级别的。
E
首先 数组的顺序是不影响最终结果的,于是先将 数组排序方便处理,不难发现我只需要知道前一个数是多少就能够对当前数进行决策,而前一个数最多只有 种情况,得到一个 的算法,定义 表示当前考虑到第 个位置,这个位置上放 的最小步数,若 为 ,则表示不替换,转移只有如下几种情况,当 时,,当 $a_i<a_{i-1} $时,对于所有满足 ,,对于所有情况, 和所有比它小的 取 的最小值,对于 的更新,采用贪心策略,,这样做是因为如果当前放 ,那么前面放 一定不劣,这样做是 的,考虑优化,发现可以将不替换的单独拿出来考虑,这个时间复杂度可以接受,只需要考虑替换时怎么维护 值,发现需要做的只有将整个数组平移一个单位和区间对一个数取 ,使用吉司机线段树维护即可。
F
不难发现如果要使用毒药,那么一定是在最开始用了若干瓶,然后又去抵消了一个前缀的回复效果,只需要枚举这个前缀是多少然后计算最优情况即可。
G
因为 和最终答案的和都是求最大值,所以可以直接去掉绝对值,这样相当于给 个数负号, 个数正号,使得和最大,显然,负号会给到数对中的较小值,正号会给到数对中的较大值,考虑什么时候给正号比给负号优,设第一对给了正号,第二对给了负号,那么给第二对正号更优当且仅当 ,发现按照 排序然后取前 个即可。
J
根据 的数量,我们可以求出 各自有多少个,以 为例,它有 个,由于 的前面也能接,后面也能接,所以我们优先处理 ,如果存在划分方案,那么将 的前 个和 配对, 的后 个和 配对,这样一定是不劣的,考虑 中用到的 ,应该是距离 最近的 , 同理,这样剩下的 一定可以配对,否则不存在划分方案。
K
如果根确定,那这题十分显然,只需要根据叶子节点的大小去搜索即可。
现在问题转化为如何确定根,考虑对于一个结点来说,它要么作为根,要么有一个父亲,考虑与这个点相邻的若干块中,影响这个点的只有最小的叶子最大的那个块,比较这个叶子和当前点谁放在序列上更优即可。
具体实现可以从最小的叶子结点开始往上找根,然后依次更新答案。
L
实际上最多只要两次即可实现,只需要找到一个前缀,让它恰好包含一种字符出现了 次,将后面区间分成两段分别覆盖一种字符即可,于是依次判断能否用 次来实现这个问题, 次直接判断, 次用双指针即可。
N
考虑对 数组操作不太好弄,因为不一定每一个 都会向下产生贡献,而 则不是,如果存在 ,那么它一定是需要被抵消的,所以每次将 数组往上推即可。