(学军集训)树

题意

给定一棵大小为 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×ciX
你可以任意调整每条边的权值,使得从根节点到每个叶子的距离都相等,请你求出
最小代价, 并输出一种方案。

对于所有测试数据,保证 1 ≤ u i ≤ i , 1 ≤ c i , d i ≤ 106 1 ≤ ui ≤ i,1 ≤ ci, di ≤ 106 1uii1ci,di106
对于 20% 的数据, 1 ≤ N ≤ 200 , 1 ≤ c i , d i ≤ 200 1 ≤ N ≤ 200,1 ≤ ci, di ≤ 200 1N200,1ci,di200;
对于 50% 的数据, 1 ≤ N ≤ 2000 , 1 ≤ c i , d i ≤ 2000 1 ≤ N ≤ 2000,1 ≤ ci, di ≤ 2000 1N2000,1ci,di2000;
对于额外 20% 的数据, d i = 1 di = 1 di=1;
对于 100% 的数据, 1 ≤ N ≤ 200000 1 ≤ N ≤ 200000 1N200000

题解

考虑暴力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子树自行解决的值。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值