2024/10/3 CSP-S模拟赛20241003
A
恶心恶心恶心,赛时写了一个二分+线段树的复杂度错了,当时yzh和lyz就一会骗我一会说实话的,搞得很懵,自己水平也是菜,那线段树分析复杂度怎么不把递归次数乘上呢?大傻逼grz
思路其实还挺好的。
你考虑很容易就发现一个性质,如果一个区间内存在两个数互质的话,这个区间的\(gcd\)肯定是\(1\)。
那么剩下的就是先做一个线段树取快速维护区间\(gcd\)的值,然后考虑双指针\(O(nlog_n^2)\)去计算所有区间得到的值,判断区间\(gcd\)答案是不是\(1\),如果是的话,那么他的贡献其实就是\(n-j+1\),因为对于这个区间的右侧你可以无线扩展,直到\(n\)为止,那么这些区间的\(gcd\)值其实都是\(1\)。
B
good题。
你考虑,可以把题目转换一下,枚举每个节点的覆盖范围,那么显然,对于这个答案,肯定是具有单调性的,直接用二分枚举每个点覆盖范围。
首先我们钦定一个点\(x\)为当前点子树内离他距离最远的节点,如图:
如图,节点\(x\)就是这个节点。
那么你考虑,根据贪心的策略,我们假设当前二分到的长度为\(mid\),那么要想要这个最后的"不满意度"最大,就需要找一个深度刚好是\(dep_x-mid\)位置的节点,为什么呢?如果选择的是\(dep_x-mid\)位置往上的节点,就无法覆盖到当前这个\(x\)节点,就需要用另外一个节点,如果在\(dep_x-mid\)位置往下的节点,就少覆盖了一些节点,就浪费了,以上便是贪心策略。
那么其实很显然,对于每一个枚举到的测量范围,我们要考虑树形\(dp\)去求这个值,那么接下来我们钦定两个\(dp\)数组:
设\(f_x\)表示以\(x\)为根节点到无法根据这个范围覆盖到最远的点的距离。
设\(g_x\)表示以\(x\)为根节点能覆盖最近的点的距离。
显然转移很好做的呀:
那么,记得初始化:\(f_x = -inf,g_x = inf\)
显然这样是不可以的,你要遵循贪心策略去求这个东西。 那么对于当前枚举到的范围,当 \(g_{x}\le mid\) 时以 \(x\) 为根的子树内所选的点覆盖不到自己,需要祖先节点进行覆盖,此时需要统计自己的贡献,即 \(f_{x}=\max(f_{x},0)\);当 \(f_{x}+g_{x} \le mid\) 时以 \(x\) 为根的子树内所选的点就能覆盖整棵子树,令 \(f_{x}=- \infty\);当 \(f_{x}=mid\) 说明 \(x\) 必须被选,令 \(f_{x}=- \infty,g_{x}=0\),选择点数加一。
特判下根节点没有被覆盖的情况。
code