原题链接
- 题意:就是给了一棵树,然后求任意两个点之间的距离异或和最大值是多少。
- 题解:很显然的是,随便定义数根,然后就是发现,如果计算 u 和 v 的边权异或和,那么就是可以是计算出 u−>root 和 v−>root,因为如果重叠的话,lca−>root⊕lca−>root 显然是 0 不影响,所以就是转化了成求出每个点到根部的异或和插入 01trie,然后再 O(n) 遍历找出每个距离根部的异或和在 trie 中最大的是多少,然后取 max 即可。
- 代码:
#include <iostream>
#include <vector>
using namespace std;
typedef long long ll;
const ll N = 200009;
struct edge {
ll v, w;
};
vector<edge>G[N];
ll d[N];
void dfs(int u, int fa) {
for (auto e:G[u]) {
if (e.v == fa)continue;
d[e.v] = d[u] ^ e.w;
dfs(e.v, u);
}
}
struct Trie {
int tr[N * 24][2], idx;
inline void insert(ll num) {
int p=0;
for (int i = 30; i >= 0; i--) {
ll id = 1&(num >> i);
if (!tr[p][id])tr[p][id] = ++idx;
p = tr[p][id];
}
}
inline ll ask(ll x) {
int p = 0;
ll ret = 0;
for (ll i = 30; i >= 0; i--) {
ll id =1& (x >> i);
if (tr[p][1^id]) {
p = tr[p][1^id];
ret += (1 << i);
} else p = tr[p][id];
}
return ret;
}
}T;
int main() {
ll n;scanf("%lld", &n);
for (int i = 1; i < n; i ++) {
ll u, v, w;
scanf("%lld%lld%lld", &u, &v, &w);
G[u].push_back({v, w});
G[v].push_back({u, w});
}
dfs(1, -1);
T.insert(0);
for (int i = 1; i <= n; i ++) {T.insert(d[i]);}
ll ans = -1;
for (int i = 1; i <= n; i ++) {
ans = max(ans, T.ask(d[i]));
}
printf("%lld\n", ans);
}
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 软件产品开发中常见的10个问题及处理方法
· .NET 原生驾驭 AI 新基建实战系列:向量数据库的应用与畅想
· 从问题排查到源码分析:ActiveMQ消费端频繁日志刷屏的秘密
· 一次Java后端服务间歇性响应慢的问题排查记录
· dotnet 源代码生成器分析器入门
· ThreeJs-16智慧城市项目(重磅以及未来发展ai)
· .NET 原生驾驭 AI 新基建实战系列(一):向量数据库的应用与畅想
· Browser-use 详细介绍&使用文档
· 软件产品开发中常见的10个问题及处理方法
· Vite CVE-2025-30208 安全漏洞