专栏文章

题解:AT_abc240_e [ABC240E] Ranges on Tree

AT_abc240_e题解参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@miq8z6qk
此快照首次捕获于
2025/12/04 00:54
3 个月前
此快照最后确认于
2025/12/04 00:54
3 个月前
查看原文
注意到我们划分的最小无交子问题一定是一个叶子节点,令其为 kk,那么答案区间显而易见的为 [1,k][1, k]
dpxdp_x 为点 xx 子树中包含的叶子节点个数,则:
dpx=uxdpudp_x = \sum_{u \in x} dp_u
边界为:dpleaf=1dp_{leaf} = 1
dp 序列可以预处理。对于答案的求取,不妨设点 xx 当前答案左边界为 pospos,则答案区间为 [pos,pos+dpx][pos, pos + dp_x]。递归时顺便传参记录一下即可。
代码:
CPP
#include <bits/stdc++.h>
#define int long long
#define pb push_back
#define fi first
#define se second
using namespace std;

const int N = 1e6 + 5;
int n, u, v, ans, dp[N];
vector<int> g[N];
pair<int, int> Ans[N];

inline void dfs(int x, int last, int pos) {
	int now = pos;

	Ans[x] = {now, now + dp[u] - 1};

	for(auto u : g[x])
		if(u != last) {
			dfs(u, x, now);

			now += dp[u];
		}
	
	return ;
}

inline void init(int x, int last) {
	if(x != 1 && g[x].size() == 1) dp[x] = 1;
	
	for(auto u : g[x])
		if(u != last) {
			init(u, x);

			dp[x] += dp[u];
		}
	
	return ;
}

signed main() {
	ios_base :: sync_with_stdio(NULL);
	cin.tie(nullptr);
	cout.tie(nullptr);

	cin >> n;
	for(int i = 1 ; i < n ; ++ i) {
		cin >> u >> v;

		g[u].pb(v), g[v].pb(u);
	}

	init(1, -1);
	dfs(1, -1, 1);

	for(int i = 1 ; i <= n ; ++ i)
		cout << Ans[i].fi << ' ' << Ans[i].se << '\n';

	return 0;
}

评论

0 条评论,欢迎与作者交流。

正在加载评论...