题意
给定一棵大小为
N
N
N,以
1
1
1 为根的有根树,每条边的初始权值是
c
i
ci
ci,单位修改代价是
d
i
d_i
di。将一条边
i
i
i 的权值修改为
X
X
X(
X
X
X 必须为整数,但可以为负) 的代价为
d
i
×
∣
c
i
−
X
∣
di × |ci − X|
di×∣ci−X∣。
你可以任意调整每条边的权值,使得从根节点到每个叶子的距离都相等,请你求出
最小代价, 并输出一种方案。
对于所有测试数据,保证
1
≤
u
i
≤
i
,
1
≤
c
i
,
d
i
≤
106
1 ≤ ui ≤ i,1 ≤ ci, di ≤ 106
1≤ui≤i,1≤ci,di≤106。
对于 20% 的数据,
1
≤
N
≤
200
,
1
≤
c
i
,
d
i
≤
200
1 ≤ N ≤ 200,1 ≤ ci, di ≤ 200
1≤N≤200,1≤ci,di≤200;
对于 50% 的数据,
1
≤
N
≤
2000
,
1
≤
c
i
,
d
i
≤
2000
1 ≤ N ≤ 2000,1 ≤ ci, di ≤ 2000
1≤N≤2000,1≤ci,di≤2000;
对于额外 20% 的数据,
d
i
=
1
di = 1
di=1;
对于 100% 的数据,
1
≤
N
≤
200000
1 ≤ N ≤ 200000
1≤N≤200000。
题解
考虑暴力DP:设
f
[
i
]
[
j
]
f[i][j]
f[i][j]为把i子树内所有叶子到i的路径变为i的最小代价,转移时还需考虑与儿子的连边,故多记一维
g
[
i
]
[
j
]
g[i][j]
g[i][j]为到
i
i
i的父亲距离为
j
j
j的最小代价,暴力转移是
O
(
n
×
c
×
n
)
O(n\times c\times n)
O(n×c×n)的。
考虑用DP值的性质来优化,先从一个叶子节点u看起,
f
[
u
]
[
0
]
=
0
f[u][0]=0
f[u][0]=0,而
g
[
u
]
[
c
[
u
]
]
=
0
,
g
[
u
]
[
i
]
g[u][c[u]]=0,g[u][i]
g[u][c[u]]=0,g[u][i]可由其转移过来,这样发现
g
[
u
]
g[u]
g[u]的值是一个下凸壳!考虑合并上去时,先将子树的
g
g
g相加,而凸壳相加后仍是凸壳,再将此凸壳先向右平移
c
[
u
]
c[u]
c[u]个单位后,再与利用
d
[
u
]
d[u]
d[u]转移后的值取
m
i
n
min
min,相当于将斜率绝对值大于
d
[
u
]
d[u]
d[u]的部分变为
d
[
u
]
d[u]
d[u]。发现每次向右平移比较麻烦,先在叶子节点平移好即可。
这样,可以维护每个节点上凸壳的顶点,合并时用线段树合并,把两端的斜率改变也可在线段树上二分、修改。
最优方案即为根节点的凸壳的最下端的点对应的取值,考虑以此递归下去得到方案:对于一个儿子
v
v
v,如果
v
v
v子树可自行解决,即无需修改
c
[
v
]
c[v]
c[v]就可符合要求,则直接下去做,否则将
c
[
v
]
c[v]
c[v]改为最接近的能使
v
v
v子树自行解决的值。