Loading

【题解】[CCO 2019] Winter Driving

给定一颗树,你需要给每条边固定一个方向,使二元组 \((x,y)\) 总数最大,\(x,y\) 满足存在一条从 \(x\) 出发到 \(y\) 的路径。

很厉害的结论题。

根据样例,我们猜测答案是以一个点为根的内向树或外向树,但是这非常的假。因为除了树退化成链的情况,其它都不是最优。

我们手玩一下菊花图,发现肯定是选择一些边从中心出发,其它边则出发到中心。

结论一:对于菊花图,最优解一定是将所有非中心点分为两部分,使得两部分 \(\sum A_i\) 的差最小。

显然,我们要在和不变的情况下使乘积最大,就是均值不等式。两边尽量均分。

怎么均分,直接背包即可。

由此我们猜测,对于任意一颗树,是否也像菊花图一样存在一个中心点呢?

结论二:对于树,最优解存在一个中心点,将该点删去后,剩下的子树都是内向树或者外向树。

不大会证明,感觉挺对的。对于一个内向树/外向树,答案可以很方便一边 DFS 求出。

那么我们怎么计算跨中心点的答案。根据结论一,我们是将这些子树分成两部分,使得 \(\sum A_i\) 的差最小即可。

这样已经能拿到 \(40\) 分了。我们在观察一些性质。

结论三:中心点一定是树的重心。注意:是原树的重心而不是对于 \(A\) 的加权重心。

这不难理解,本质还是均值不等式。但是我不大会严谨证明。

一棵树最多只有两个重心,所以等价于我们只用求两次菊花图的答案然后取最大值。

由于值域比较大,不太能背包。但是题目有性质 \(D\le 36\),所以直接折半搜索即可。

#define N 270005
int n, sz[N], a[N], X, Y; LL sum, ans, mx;
vector<int>e[N];
void get(int x,int fa){
	sz[x] = 1; int cur = 0;
	go(y, e[x])if(y != fa)get(y, x), sz[x] += sz[y], cmx(cur, sz[y]);
	cmx(cur, n - sz[x]);
	if(cur * 2 <= n)Y = x, swap(X, Y);
}
void dfs(int x,int fa){
	sz[x] = 0;
	go(y, e[x])if(y != fa)dfs(y, x), sz[x] += sz[y];
	sum += a[x] * 1LL * (sz[x] + a[x] - 1), sz[x] += a[x];
}
int u[40], p[N], q[N], l, r;
void ins1(int x,int s){
	if(x == 19)p[++l] = s;
	else{
		if(u[x])ins1(x + 1, s + u[x]);
		ins1(x + 1, s);
	}
}
void ins2(int x,int s){
	if(x == 37)q[++r] = s;
	else{
		if(u[x])ins2(x + 1, s + u[x]);
		ins2(x + 1, s);
	}
}
LL calc(int x){
	int t = 0; mx = 0, l = r = 0;
	memset(u, 0, sizeof(u));
	go(y, e[x])u[++t] = sz[y];
	ins1(1, 0), ins2(19, 0);
	sort(p + 1, p + l + 1), sort(q + 1, q + r + 1);
	l = unique(p + 1, p + l + 1) - p - 1, 
	r = unique(q + 1, q + r + 1) - q - 1;
	int lim = (sz[x] - a[x]) / 2;
	rp(i, l){
		int j = lower_bound(q + 1, q + r + 1, lim - p[i]) - q;
		if(j <= r)cmx(mx, (p[i] + q[j]) * 1LL * (sz[x] - a[x] - p[i] - q[j]));
	}return mx;
}
void check(int x){sum = 0, dfs(x, 0), cmx(ans, sum + calc(x));}
int main() {
	read(n);
	rp(i, n)read(a[i]);
	rp(i, n - 1){
		int x; read(x);
		e[x].pb(i + 1), e[i + 1].pb(x);
	}
	get(1, 0);
	check(X); if(Y)check(Y);
	printf("%lld\n", ans);
	return 0;
}
posted @ 2022-04-10 15:28  7KByte  阅读(102)  评论(0编辑  收藏  举报