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\)

code

B

good题。
你考虑,可以把题目转换一下,枚举每个节点的覆盖范围,那么显然,对于这个答案,肯定是具有单调性的,直接用二分枚举每个点覆盖范围。

首先我们钦定一个点\(x\)为当前点子树内离他距离最远的节点,如图:

如图,节点\(x\)就是这个节点。
那么你考虑,根据贪心的策略,我们假设当前二分到的长度为\(mid\),那么要想要这个最后的"不满意度"最大,就需要找一个深度刚好是\(dep_x-mid\)位置的节点,为什么呢?如果选择的是\(dep_x-mid\)位置往上的节点,就无法覆盖到当前这个\(x\)节点,就需要用另外一个节点,如果在\(dep_x-mid\)位置往下的节点,就少覆盖了一些节点,就浪费了,以上便是贪心策略。

那么其实很显然,对于每一个枚举到的测量范围,我们要考虑树形\(dp\)去求这个值,那么接下来我们钦定两个\(dp\)数组:
\(f_x\)表示以\(x\)为根节点到无法根据这个范围覆盖到最远的点的距离。
\(g_x\)表示以\(x\)为根节点能覆盖最近的点的距离。
显然转移很好做的呀:

\[\begin{cases} f_{x}=\max\limits_{y \in son(x)}\{ f_{y}+1 \} \\ g_{x}=\min\limits_{y \in son(x)}\{ g_{y}+1 \}\end{cases} \]

那么,记得初始化:\(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

posted @ 2024-10-03 21:12  Lunar_Whisper  阅读(5)  评论(0编辑  收藏  举报