Nuisdete @ 2023-02-10 16:46:21
RT.
目前只从惩罚角度感性理解 wqs 二分,对于最后答案的输出有个问题,我记得最后输出的答案应该是二分到的答案
#include <cstdio>
#include <vector>
#include <utility>
#define fst first
#define sec second
typedef long long LL;
typedef std::pair<int, int> pii;
const int MAXN = 3e5 + 5;
const LL INF = 0x3f3f3f3f3f3f3f3f;
int n, m;
struct Str {
LL val; int cnt;
Str operator+ (const Str& A) const {
Str res;
res.val = val + A.val, res.cnt = cnt + A.cnt;
return res;
}
} f[MAXN << 1][3];
std::vector<pii> G[MAXN << 1];
LL ext;
Str MAX(Str A, const Str B) {
if (A.val == B.val) return A.cnt > B.cnt ? A : B;
return A.val > B.val ? A : B;
}
void dfs(int u, int father) {
for (auto x : G[u]) {
int k = x.fst, val = x.sec;
if (k != father) {
dfs(k, u);
f[u][2] = MAX(f[u][2] + f[k][0], f[u][1] + f[k][1] + (Str){ val - ext, -1 });
f[u][1] = MAX(f[u][1] + f[k][0], f[u][0] + f[k][1] + (Str){ val, 0 });
f[u][0] = f[u][0] + f[k][0];
}
}
f[u][0] = MAX(MAX(f[u][0], f[u][1]), f[u][2]);
}
void solve(LL mid) {
ext = mid;
for (int i = 1; i <= n; ++i) {
f[i][0] = (Str){ 0LL, 0 };
f[i][1] = (Str){ ext, 1 };
f[i][2] = (Str){ -INF, 0 };
}
dfs(1, 0);
}
int main() {
scanf("%d %d", &n, &m); ++m;
for (int i = 1; i < n; ++i) {
int x, y, val;
scanf("%d %d %d", &x, &y, &val);
G[x].emplace_back(y, val), G[y].emplace_back(x, val);
}
LL l = -1e12, r = 1e12, res;
while (l <= r) {
LL mid = l + r >> 1;
solve(mid);
if (f[1][0].cnt <= m) res = mid, l = mid + 1;
else r = mid - 1;
}
solve(res);
printf("%lld\n", f[1][0].val - res * m);
return 0;
}
发现之前的讨论帖也有人有这个问题:link
按照下面人的回答更改了代码并通过了此题,但是似乎与 wqs 二分的正确的答案输出相反,而且题解都是按照我理解的正确的输出方式输出的。
是代码有 bug 并碰巧数据水然后过了吗?
by Rosaya @ 2023-02-10 17:26:41
如果斜率相同的话可能是正好切不到横坐标为 k 的点的,但是这时候因为斜率相同正好可以拿端点值算,所以应该输出端点值。
by Nuisdete @ 2023-02-10 17:37:32
@Dark_night_qwq 但是题目要求恰好为 k,端点值并不一定与横坐标为 k 的值相等吧。我的理解是此时端点的斜率与横坐标为 k 的相等,所以可以计算出横坐标为 k 时的答案。
by Nuisdete @ 2023-02-10 17:38:35
但是为什么要输出端点值?
by Rosaya @ 2023-02-10 18:27:35
@louis_11 哦,我知道了,是您前面的 max 有问题。
就是您让值相同时选 cnt 大的,导致如果斜率相同的话切的是大的。
这时候因为 cnt>m 导致答案没有更新,所以切错了。
我前面纯纯扯淡了。
by Nuisdete @ 2023-02-10 18:48:08
@Dark_night_qwq orz 谢谢您。