CF1656E Equal Tree Sums Sol
可以用归纳法解题。
首先发现,删掉一个点,剩下的块数就是它的度数。
不妨使得 ,一个点的点权等于其他所有点权的和的相反数。
发现度数是相互提供的,则相邻的点的正负性一定相反。
考虑如何进行具体构造。
设当前点 ,其父亲为 , 的 棵子树的和均为 ,剩余连通块的和也为 。
那么 。
考虑转移到 ,其以 为根的子树和为 。
同理有其余子树(加上 的共 个)和连通块的和为 。
那么 。
以 为根的子树和为 。
那么你会发现,子树和呈交替的 的状态。这是什么原因呢?
其实对于每一棵子树来说,它自己本身就是一个合法状态。
那么此时它只有一个父亲,会贡献 的度数,且由于相邻点权正负性相反,于是存在 。
这样构造,子树和就与点权没关系了,只和深度有关,为 或 。
将叶子节点均赋为 或 ,往上递归即可(为了保证点权不超过限制)。
稍微想一下发现不需要反过来求和,点权的绝对值其实就是它的度数,正负性由深度决定。
#pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10, M = N << 4;
int t, n, cnt, qu[N], dep[N], lst[N], res[N], head[N];
struct Edge { int to, nxt; } e[N << 1];
namespace fast_io {
int it, ed, ot, t; char stk[20], bf[N + 50], ob[N + 50];
#define gc (it == ed && (ed = (it = 0) + fread(bf, 1, N, stdin), it == ed))? EOF : bf[it++]
template <typename T> inline void read(T &x) {
x = 0; char ch = gc; int f = 1;
for (; !isdigit(ch); ch = gc) if (ch == '-') f = -1;
for (; isdigit(ch); ch = gc) x = x * 10 + (ch ^ 48); x *= f; return ;
} template <typename T, typename ...Args>
inline void read(T &x, Args &...args) { read(x), read(args...); }
inline void fls() { fwrite(ob, 1, ot, stdout), ot = 0; }
template <typename T> inline void write(T x, char opt) {
if (x < 0) ob[ot++] = '-', x = -x;
while (x > 9) stk[++t] = 48 ^ (x % 10), x /= 10;
for (ob[ot++] = 48 ^ x; t; ob[ot++] = stk[t--]);
ob[ot++] = opt; if (ot > N) fls(); return ;
}
} using fast_io::read; using fast_io::write;
inline void addEdge(int u, int v) {
e[++cnt].to = v, e[cnt].nxt = head[u];
head[u] = cnt;
}
inline void solve() {
read(n); cnt = 0; for (int i = 1; i <= n; ++i) head[i] = res[i] = 0;
for (int i = 1, u, v; i < n; ++i)
read(u, v), addEdge(u, v), addEdge(v, u), ++res[u], ++res[v];
int l = 1, r = 1; qu[l] = dep[l] = lst[l] = 1;
while (l <= r) {
int f = lst[l], cur = qu[l], dp = dep[l]; ++l;
for (int i = head[cur]; i; i = e[i].nxt) {
int to = e[i].to;
if (to ^ f) ++r, lst[r] = cur, qu[r] = to, dep[r] = -dp;
}
res[cur] *= dp;
}
for (int i = 1; i <= n; ++i) write(res[i], i == n? '\n' : ' ');
}
int main() {
read(t); while (t--) solve(); fast_io::fls(); return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现