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)