NOIP2020 做题练习(day3)

A - 金牌赛事

题面

Codeforces 原题

首先设 (dp_i) 表示考虑前 (i) 条道路的最大利润。

转移:(dp_i=max{dp_{i-1}, maxlimits_{j=0}^{i-1}{dp_j-s(j+1,i)+w(j+1,i)}})

其中 (s(j+1,i)) 表示修理道路 ([j+1,i]) 的费用之和,即 (sumlimits_{k=j+1}^i c_k)(w(j+1,i)) 表示道路 ([j+1,i]) 所有赛事的利润之和。

后面的式子可以用线段树维护,具体就是每一个节点 (i) 维护 (dp_i-c_i+)(i) 为终点的赛事利润之和。

右端点每次位移就相当于进行区间修改操作。

代码

B - 公园晨跑

题面

Codeforces 原题

把边的贡献转移到点上,断环成链,然后又变成了一个区间查询的线段树。

注意特判选择两个点重合的情况,这个时候就需要固定一个端点后取最大值。

代码

C - 幸运树

题面

Codeforces 原题

容斥之后直接并查集算答案,注意别算重。

代码

D - 一堆的堆

题面

Codeforces 原题

注意到 (i) 叉堆点 (j) 的儿子范围是 ([j imes i-i+2,j imes i+1]),那么可以先对整个序列排序,再用一个树状数组维护不合法节点数量。复杂度为调和级数。

代码

E - 赛道修建

题面

首先二分答案。

然后在 dfs 的过程中,每次传上来一条以儿子节点为头的最长链,用一个 multiset 从小到大匹配。

注意二分上界要调到树的直径才能过。

代码

原文地址:https://www.cnblogs.com/xsl19/p/13697980.html