专栏文章
题解: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 个月前
注意到我们划分的最小无交子问题一定是一个叶子节点,令其为 ,那么答案区间显而易见的为 。
设 为点 子树中包含的叶子节点个数,则:
边界为:。
dp 序列可以预处理。对于答案的求取,不妨设点 当前答案左边界为 ,则答案区间为 。递归时顺便传参记录一下即可。
代码:
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 条评论,欢迎与作者交流。
正在加载评论...