D. Score of a Tree
D. Score of a Tree
You are given a tree of nodes, rooted at . Every node has a value of either or at time .
At any integer time , the value of a node becomes the bitwise XOR of the values of its children at time ; the values of leaves become since they don't have any children.
Let denote the sum of values of all nodes at time .
Let denote the sum of across all values of such that , where is the initial assignment of s and s in the tree.
The task is to find the sum of for all initial configurations of s and s in the tree. Print the sum modulo .
Input
Each test contains multiple test cases. The first line contains the number of test cases (). The description of the test cases follows.
The first line of each test case contains () — the number of nodes in the tree.
The next lines of each test case contain two integers each — , indicating an edge between and ().
It is guaranteed that the sum of over all test cases does not exceed .
Output
Output the sum modulo for each test case.
Example
Input
1
6
1 2
1 3
3 4
3 5
3 6
Output
288
Note
Let us find for the configuration ( denotes the value of node ). Initially (at ) our tree is as shown in the picture below. In each node, two values are shown: the number and the value of this node. for this configuration is .
At the configuration changes to . The tree looks as shown below. .
At the configuration changes to . The tree looks as shown below. .
For all , the graph remains unchanged, so for all . So, for the initial configuration , the value of .
Doing this process for all possible configurations yields us an answer of .
解题思路
官方给出的做法是用期望做的,我有点看不懂,这里给出另外一种思路和做法。
最重要的是要发现以下性质,在以 为根的子树中, 时刻节点 的值等于子树中所有距离 为 的节点的初始值的异或和。只需模拟一下就可以发现这个性质。
可以知道当固定了初始方案后,每个节点对答案的贡献只取决于以该节点为根子树中所有同一深度的节点的初始值的异或和,所以每个节点对答案的贡献是独立的。因此为了统计所有初始方案的 ,我们可以单独考虑每个节点在所有初始方案中的贡献,然后再求和。
假设以 为根的子树的最大深度为 (根节点 的深度为 ),那么只有当 时节点 才会对答案有贡献。同时若 要在 时刻对答案有贡献,那么就要求距离 为 的节点异或和是 ,即这些节点中初始值为 的节点个数是奇数个。假设距离 为 的节点有 个,那么在所有的初始方案中,这些节点中有奇数个初始值为 的方案数就是 。
由二项式定理 ,当取 时,有 ,即二项式展开式中奇数项系数之和等于偶数项系数之和,且值为 。因此有 ,是一个定值。
由于在 时才有贡献,因此 在所有的初始方案中的贡献就是 ,所以最终答案就是 。
只需 dfs 求出以每个节点为根的子树的最大深度,然后乘上 并累加到答案即可。
AC 代码如下,时间复杂度为 :
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 2e5 + 10, M = N * 2, mod = 1e9 + 7;
int head[N], e[M], ne[M], idx;
int p, ans;
void add(int u, int v) {
e[idx] = v, ne[idx] = head[u], head[u] = idx++;
}
int dfs(int u, int pre) {
int d = 1;
for (int i = head[u]; i != -1; i = ne[i]) {
if (e[i] != pre) d = max(d, dfs(e[i], u) + 1);
}
ans = (ans + 1ll * p * d) % mod;
return d;
}
void solve() {
int n;
scanf("%d", &n);
memset(head, -1, n + 10 << 2);
idx = 0, p = 1;
for (int i = 0; i < n - 1; i++) {
int u, v;
scanf("%d %d", &u, &v);
add(u, v), add(v, u);
p = p * 2 % mod;
}
ans = 0;
dfs(1, -1);
printf("%d\n", ans);
}
int main() {
int t;
scanf("%d", &t);
while (t--) {
solve();
}
return 0;
}
参考资料
Codeforces Round #845(div2)题解(A-E):https://www.bilibili.com/video/BV1eG4y1F7KV/
Codeforces Round #845 (Div. 2) and ByteRace 2023 Editorial:https://codeforces.com/blog/entry/111729
本文来自博客园,作者:onlyblues,转载请注明原文链接:https://www.cnblogs.com/onlyblues/p/17831948.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
2022-11-14 B. Diverse Substrings
2022-11-14 Maximum Number of Non-overlapping Palindrome Substrings
2022-11-14 Minimum Number of Operations to Sort a Binary Tree by Level