关于二分的初始值
查看原帖
关于二分的初始值
141393
Dyd本人楼主2022/6/5 21:57

先发 AC 代码:

#include <bits/stdc++.h>
using LL = long long;
const int N = 3e5 + 100;
const int inf = 0x3f3f3f3f;
const LL INF = 1e18;
int n, num, l, r, mid;
struct Edge{ int ne, ver, w; } e[N << 1];
int h[N], idx = 0;
struct DP
{
	LL v; int num;
	bool operator < (DP x) const { return v == x.v ? num > x.num : v < x.v; }
	DP operator + (DP x){ return {v + x.v, num + x.num}; }
} d[N][3], as, td[3];
LL ans;
void add(int x, int y, int z){ e[idx] = {h[x], y, z}, h[x] = idx++; }
template<typename T>
bool cmx(T &x, T y){ return x < y ? x = y, true : false; }
void dp(int x, int fa)
{
	for (int i = h[x], y; ~i; i = e[i].ne) if ((y = e[i].ver) != fa)
	{
		dp(y, x);
		for (int j = 0; j <= 2; ++j) td[j] = {-INF, inf};
		for (int j = 0; j <= 2; ++j)
			for (int k = 0; k <= 2; ++k) cmx(td[j], d[x][j] + d[y][k]);
		cmx(td[1], d[x][0] + d[y][0] + DP{e[i].w - mid, 1});
		cmx(td[1], d[x][0] + d[y][1] + DP{e[i].w, 0});
		cmx(td[2], d[x][1] + d[y][0] + DP{e[i].w, 0});
		cmx(td[2], d[x][1] + d[y][1] + DP{e[i].w + mid, -1});
		for (int j = 0; j <= 2; ++j) d[x][j] = td[j];
	}
}
int main()
{
	scanf("%d %d", &n, &num);
	memset(h + 1, -1, n << 2);
	for (int i = 1, u, v, w; i < n; ++i)
	{
		scanf("%d %d %d", &u, &v, &w);
		add(u, v, w), add(v, u, w);
	}
	l = -1e12, r = 1e12;
	while (l <= r)
	{
		mid = (l + r) >> 1;
		for (int i = 1; i <= n; ++i)
		{
			d[i][0] = {0, 0};
			d[i][1] = {-INF, inf};
			d[i][2] = {-mid, 1};
		}
		dp(1, 0);
		as = d[1][0], cmx(as, d[1][1]), cmx(as, d[1][2]);
		if (as.num <= num + 1)
		{
			ans = as.v + LL(mid) * (num + 1);
			r = mid - 1;
		}
		else l = mid + 1;
	}
	printf("%lld\n", ans);
	return 0;
}

4343 行如果写成 l = -1e6, r = 1e6 就会 WA 成 40pts40pts

所以蒟蒻想问问:为啥 l,rl, r 要定那么大?(或者说,wqs 二分如何确定 l,rl, r 初始值该定多大?)

2022/6/5 21:57
加载中...