ABC214

AtCoder Beginner Contest 214

D - Sum of Maximum Weights

题意

给出一颗 NN 个顶点的树,每条边都具有边权值,定义与顶点有关的二元函数 f(u,v)f(u, v) 为 顶点 uu 到顶点 vv 的最短路径上的边权的最大值。

i=1N1j=i+1Nf(i,j)\sum_{i=1}^{N-1}\sum_{j=i+1}^{N} f(i,j)

其中 N105N \leqslant 10^5

思路

最一开始以为是树形dp,在那想半天换根,其实根本不用

题目只要求取路劲上边权的最大值,那么可以将边权排序,然后从小到大地加入到图中,每次加入新边 ee 时,两个顶点的连通集中的点必定通过 ee,并且 ee 是路径上边权最大的边,对左右两个连通集中的点的答案产生贡献。

可以使用并查集维护连通集,总复杂度 O(NlogN)O(NlogN),并查集复杂度远小于 O(logN)O(logN)

E - Packing Under Range Regulations

题意

在区间 [1,109][1,10^9] 上有编号 1,,N1,\ldots,N 个球要放,每个位置上只能放一个球,对于编号 ii 的球,要求:必须放在区间 [Li,Ri][L_i,R_i] 之间,给出每一个球对应的要求区间,判断是否存在可行解?

多组数据,N2×105N\leqslant 2\times 10^5

思路

考虑从从左到右扫过去,对于当前扫到的位置 ii,如果该位置上有左端点 LjL_j 那么将其对应的 RjR_j 推入大根堆中,这样就可以保证堆中元素的左端点 LjiL_j\leqslant i,那么只需要判断是否有 RjiR_j\geqslant i,如果成立,则弹出,将当前位置放上堆顶对应的球,否则一定无解,因为每次都是贪心取得距离当前位置最近的顶点,如果将堆顶对应的球提前放入,那么一定会有另一个求无法放入其中,所以如果不满足条件一定无解。

实现的时候,需要对左端点进行离散处理,然后进行上述模拟操作,总复杂度 O(NlogN)O(NlogN)

F - Substrings

题意

给出一个长度为 NN 的由小写英文字母组成的字符串 SS,选出一个由 SS 的子序列构成的字符串 TT,并保证该子序列中的元素不相邻,也就是对 TT 的下标 {am}\{a_m\}T=Sa1Sa2SamT=S_{a_1}S_{a_2}\cdots S_{a_m},有 i,ai+1ai+1\forall i, a_i+1\neq a_{i+1}。求一共有多少不同的字符串 TT,答案对 109+710^9+7 取模。

N2×105N\leqslant 2\times 10^5

思路

这个题能使用dp,而且复杂度很奇妙。

dp能够处理子序列问题,这在以前都很常见,我们先不考虑序列中元素不相邻这个要求,令 f(i)f(i)SS 串上前 ii 个字符组成的子序列的个数,保证字符 SiS_i 总被使用到。

则有转移

f(i)=j=kii1f(j)f(i)=\sum_{j=k_i}^{i-1}f(j)

其中 kik_i 表示最大的满足 Ski=SiS_{k_i}=S_i 的下标,因为要保证生成的子序列不同,如果遇到了和当前 SiS_i 相同的字符那么之间的字符在加上字符 SiS_i 会和 SkiS_{k_i} 重复,所以之前的都不用计算了。

这个时间复杂度是 O(26N)O(26N),因为考虑一种字符,它的最大的遍历距离是 NN,比如 abbccccbaabbccccba,那么 aa 遍历距离为8, bb 遍历距离为1+5, cc 遍历距离为1+1+1,所以每种字符的遍历的最大距离都不会超过 NN,于是复杂度就正确了。

现在加上条件,两个下标不能相邻,那么只需修改下转移方程:

f(i)=j=kii2f(j)f(i) = \sum_{j=k_i}^{i-2}f(j)

其中 kik_i 为最大的满足 Ski+1SiS_{k_i+1}\neq S_i 的下标,因为遇到了相同的字符 Sk=SiS_k=S_i 那么它开始取的位置是 k2k-2 处,所以 f(k1)f(k-1) 处的值还是要加上的。

总复杂度 O(26N)O(26N)


ABC214
https://wty-yy.github.io/posts/4823/
作者
wty
发布于
2021年8月15日
许可协议