[vp]CF1529(div2)

https://codeforces.com/contest/1529

\(A\)
选择最小的数,其他数都会被删去,最后只剩下最小的数。
排序统计一下最小数的个数即可。

\(O(nlog_n)\)

\(B\)
很显然正整数只能选择一个,非正数可以全部一起选。
我们先统计非正数的个数,然后选择最小的正数,
判断是否会使非正数个数减少(排序后检查相邻的),如果更劣就不选。

\(O(nlog_n)\)

\(C\)
显然每个点只有\(l_i\)\(r_i\)两种取值,
然后直接树\(dp\)
\(dp_{v,0}+=max(dp_{u,0}+|l_v−l_u|,dp_{u,1}+|l_v−r_u|)\)
\(dp_{v,1}+=max(dp_{u,0}+|r_v−l_u|,dp_{u,1}+|r_v−r_u|)\)

\(D\)

我们考虑点\(1\)连出去的点\(x\)
如果\(x>n\),那么\(2,3,4...\)连出的长度都应该与\(1\)相等,最后就只剩下中间的一块空白,
(画图理解即可)
而这块空白就是一个独立的子问题
如果\(x\) \(<\) \(n\),那么很显然就是多个不相交的相等的连线,所以个数便是\(n\)约数的个数。
那么设\(f_n\)\(n\)的答案。
所以\(f_n =D(n)+ \sum_{i=0}^{n-1}f_i\),(\(D(n)\)表示\(n\)的约数个数)
提前筛出\(D(n)\),前缀和统计\(f(n)\),即可\(O(1)\)转移。

\(O(n)\)

\(E\)

我们设两棵树为\(A\)树和\(B\)
将题目转化一下就是让我们在\(A\)中找一条以根节点为起点的链,
从上面选出尽量多的点,使得每个点在\(B\)树中都不是另一个点的祖先。
\(A\)树进行一遍\(dfs\),动态维护一个点集,设我们要加入的当前点为\(u\)
我们只需要在点集中查找是否会有一个点\(v\)使得\(u\)无法加入点集,
不存在我们直接加入,否则就是以下两种情况。
(以下对于\(B\)树)

\(1\). 如果\(v\)\(u\)的子树里,根据贪心中的决策包容性,深度越大的更优,我们跳过\(u\)这个点。
\(2\). 如果\(v\)\(u\)的祖先,同理,我们去掉\(v\),换成\(u\)

我们把加入的点在\(B\)树中染成黑色,那么也就是询问:

\(1\). \(u\)的子树里是否有黑点。
\(2\). \(u\)\(1\)的路径上是否有黑点。

用树剖维护信息(黑色看成\(1\),白色看成\(0\),支持单点修改,查询最值)。

\(O(nlog_n)\)

\(F\)

如果没有停留这个功能的话,直接用\(dijkstra\)就行,
重点在于如何处理停留。
我们建\(n\)条新边\((i,(i+1) mod~n,1)\)
如果此时要停留\(c\)秒从\(u\)\(v\),
等价于先到\(v-c\),然后再走新边\(c\)次到达\(v\)
显然第一次不能走新边,否则相当于多等了一秒。
我们对于每个点跑一次\(dijkstra\)即可。
注意这题边数过多,只能用没有堆优化的\(dijkstra\)

posted @ 2021-05-27 16:46  Isenthalpic  阅读(62)  评论(0编辑  收藏  举报