AtCoder Beginner Contest 214
D - Sum of Maximum Weights
题意
给出一颗 N 个顶点的树,每条边都具有边权值,定义与顶点有关的二元函数 f(u,v) 为 顶点 u 到顶点 v 的最短路径上的边权的最大值。
求
i=1∑N−1j=i+1∑Nf(i,j)
其中 N⩽105
思路
最一开始以为是树形dp,在那想半天换根,其实根本不用
题目只要求取路劲上边权的最大值,那么可以将边权排序,然后从小到大地加入到图中,每次加入新边 e 时,两个顶点的连通集中的点必定通过 e,并且 e 是路径上边权最大的边,对左右两个连通集中的点的答案产生贡献。
可以使用并查集维护连通集,总复杂度 O(NlogN),并查集复杂度远小于 O(logN)。
点击显/隐代码
E - Packing Under Range Regulations
题意
在区间 [1,109] 上有编号 1,…,N 个球要放,每个位置上只能放一个球,对于编号 i 的球,要求:必须放在区间 [Li,Ri] 之间,给出每一个球对应的要求区间,判断是否存在可行解?
多组数据,N⩽2×105
思路
考虑从从左到右扫过去,对于当前扫到的位置 i,如果该位置上有左端点 Lj 那么将其对应的 Rj 推入大根堆中,这样就可以保证堆中元素的左端点 Lj⩽i,那么只需要判断是否有 Rj⩾i,如果成立,则弹出,将当前位置放上堆顶对应的球,否则一定无解,因为每次都是贪心取得距离当前位置最近的顶点,如果将堆顶对应的球提前放入,那么一定会有另一个求无法放入其中,所以如果不满足条件一定无解。
实现的时候,需要对左端点进行离散处理,然后进行上述模拟操作,总复杂度 O(NlogN)
点击显/隐代码
F - Substrings
题意
给出一个长度为 N 的由小写英文字母组成的字符串 S,选出一个由 S 的子序列构成的字符串 T,并保证该子序列中的元素不相邻,也就是对 T 的下标 {am},T=Sa1Sa2⋯Sam,有 ∀i,ai+1=ai+1。求一共有多少不同的字符串 T,答案对 109+7 取模。
N⩽2×105
思路
这个题能使用dp,而且复杂度很奇妙。
dp能够处理子序列问题,这在以前都很常见,我们先不考虑序列中元素不相邻这个要求,令 f(i) 为 S 串上前 i 个字符组成的子序列的个数,保证字符 Si 总被使用到。
则有转移
f(i)=j=ki∑i−1f(j)
其中 ki 表示最大的满足 Ski=Si 的下标,因为要保证生成的子序列不同,如果遇到了和当前 Si 相同的字符那么之间的字符在加上字符 Si 会和 Ski 重复,所以之前的都不用计算了。
这个时间复杂度是 O(26N),因为考虑一种字符,它的最大的遍历距离是 N,比如 abbccccba,那么 a 遍历距离为8, b 遍历距离为1+5, c 遍历距离为1+1+1,所以每种字符的遍历的最大距离都不会超过 N,于是复杂度就正确了。
现在加上条件,两个下标不能相邻,那么只需修改下转移方程:
f(i)=j=ki∑i−2f(j)
其中 ki 为最大的满足 Ski+1=Si 的下标,因为遇到了相同的字符 Sk=Si 那么它开始取的位置是 k−2 处,所以 f(k−1) 处的值还是要加上的。
总复杂度 O(26N)
点击显/隐代码