uoj418

题意

uoj

做法

下面考虑算\(ans_1\),也就是全局

将操作拍成一个序列,一个显然的贪心是放\(w_i\)后取出\(\sum\limits_{v\in son_i}w_v\),相当于到一个点\(i\)时,\(A_i=+w_i-\sum\limits_{v\in son_i}w_v\),求最大前缀和

这样会发生一个问题,就是怎么构造这个序列,先选完儿子才能选父亲,很不好搞

这样转换:把操作序列倒过来看,就是先选父亲,才能选儿子节点。
之前比如在相对序列中儿子值的变化:\(\{son_1(+w_{1}),...,son_2(+w_{2}),...,son_3(+w_3),...fa(-w_1-w_2-w_3)\}\)
现在等价于:\(\{fa(+w_1+w_2+w_3)\},...,son_3(-w_3),...,son_2(-w_2),...,son_1(-w_1)\)
对于序列上的某个点\(i\),定义二元组\((+\sum\limits_{v\in son_i}w_v-w_i,+\sum\limits_{v\in son_i}w_v)\)表示经过该点后的增量、历史最大增量

合并是显然的:\((x,y)+(x',y')=(x+x',max(y,x+y'))\)

然后这样的二元组是有严格的优先级的:

  • \(x<0\)的,优先放前面;多个\(x<0\)的,\(y\)较小的放前面
  • \((x,y),(x',y')(x,x'>0)\)\((x,y)\)放前面当且仅当:\(max(y,x+y')<max(y',x'+y)\),由于\(x,x'>0\),等价于\(x+y'<x'+y\Longrightarrow x-y<x'-y'\)

然后贪心的做这个,当取出的点\(i\)其父亲还没取出来时,令其与父亲合并,由于可能有多个点与父亲合并,用链表维护。(这里强烈建议找份代码看一下)
做全局解后,显然某个子树的解是全局解的子序列,就用线段树合并来维护即可

猜你喜欢

转载自www.cnblogs.com/Grice/p/12822602.html