分析:
第一次看这个题:这不就是一个点分治么
统计长度为x的路径最大权值
然而在点分治中统计这个信息的复杂度实际上还是
O(n2)
O
(
n
2
)
(处理出dis,还是要枚举端点,这和bzoj2599不一样啊)
而且最后的答案也不好搞啊
由于我们要最大化
∑w[i]∗x[i]∑x[i]
∑
w
[
i
]
∗
x
[
i
]
∑
x
[
i
]
可以考虑01分数规划
设
F(L)=∑w[i]∗x[i]−L∗∑x[i]=∑(w[i]−L)∗x[i]
F
(
L
)
=
∑
w
[
i
]
∗
x
[
i
]
−
L
∗
∑
x
[
i
]
=
∑
(
w
[
i
]
−
L
)
∗
x
[
i
]
当
F(L)>0
F
(
L
)
>
0
即
∑w[i]∗x[i]∑x[i]>L
∑
w
[
i
]
∗
x
[
i
]
∑
x
[
i
]
>
L
,则存在答案大于
L
L
二分答案,把边权设为,判断树中是否有路径和大于
0
0
且长度在的路径
设
mx[i]
m
x
[
i
]
,表示长度为
i
i
<script type="math/tex" id="MathJax-Element-22">i</script>的最长路径
计算当前子树的时候用bfs进行遍历,这样可以保证长度单调不降
那么在统计答案的时候就可以维护一个权值单调递减的单调栈,线性的更新答案
二分写在里面还是写在外面?
不少前辈都说二分在点分治内部的效率要高于外层,因为这样不用每次check的时候都找重心
然而终于看到了不同的声音(以下内容转自dada的blog)
网上很多都说写在里面快,而我的同学PoPoQQQ大爷实测是写在外面快。
所以当然是写在外面快!!!
(并不是因为“实测”,而是因为这是大爷说的!!! 2333)下面给出一定的分析。
首先写在里面的话是对于每个重心更新答案之后,之后的重心在处理时下边界会增大,这样的话实际上时间受影响于每次在当前重心更新的幅度。
而写在外面的话,则是严格完整时间复杂度?并不是的。我们在某个重心进行处理时发现符合要求的答案时,可以直接跳出。写在里面是一点一点调整答案,但是调整的幅度欠佳,因为还有一个上界未被改变(这个我不确定是否有下调上界的剪枝,没有细想,不要D我)。
而写在外面则是大步跳,每次得到mid以后期望很快得到一个重心可以求出符合答案的解,也就是很多重心不需要被处理,剪枝的幅度比较大。
tip
代码不好写,高仿都不成。。。
真的不想写了,坑着吧