博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
AcWing 144. 最长异或值路径 01字典树打卡
阅读量:4614 次
发布时间:2019-06-09

本文共 1391 字,大约阅读时间需要 4 分钟。

给定一个树,树上的边都具有权值。

树中一条路径的异或长度被定义为路径上所有边的权值的异或和:

formula.png

⊕ 为异或符号。

给定上述的具有n个节点的树,你能找到异或长度最大的路径吗?

输入格式

第一行包含整数n,表示树的节点数目。

接下来n-1行,每行包括三个整数u,v,w,表示节点u和节点v之间有一条边权重为w。

输出格式

输出一个整数,表示异或长度最大的路径的最大异或和。

数据范围

1n1000001≤n≤100000,

0u,v<n0≤u,v<n,
0w<2310≤w<231

输入样例:

40 1 31 2 41 3 6

输出样例:

7

样例解释

样例中最长异或值路径应为0->1->2,值为7 (=3 ⊕ 4)

 

题意:这是求任意两点之间的路径的所有值

思路:我们设置一个数组D[i]=D[father]^w[father][i]  代表根节点到当前点的异或值

然后我们任意选两点之间的路径其实也就是D[i]^D[j],为什么呢,因为这是一棵树,我们0-x,0-y,中间有一部分路径是重复的,我们两个异或之后就会抵消掉,然后这个题就可以转换为

求最大异或对,所以我们只要最开始dfs一下,然后求最大异或对即可

 

 

#include
#define maxn 100005#define mod 1000000007using namespace std;typedef long long ll;ll n,top;ll a[maxn];ll tree[maxn*32][2];ll d[maxn];vector
> mp[maxn];void insert(ll x){ ll root=0; for(int i=0;i<32;i++){ ll z=(x>>(31-i))&1; if(!tree[root][z]) tree[root][z]=++top; root=tree[root][z]; } }ll query(ll x){ ll root=0; ll sum=0; for(int i=0;i<32;i++){ ll z=(x>>(31-i))&1; if(tree[root][!z]){ sum+=1<<(31-i); root=tree[root][!z]; } else{ root=tree[root][z]; } } return sum;}void dfs(ll x,ll f){ //cout<
<
v=mp[x][i]; if(v.first==f) continue; d[v.first]=d[x]^(v.second); // cout<
<

 

转载于:https://www.cnblogs.com/Lis-/p/10897042.html

你可能感兴趣的文章
Algorithm
查看>>
微积分初步
查看>>
毕业论文格式范例讲解
查看>>
js的块级作用域
查看>>
委托、Lambda表达式和事件
查看>>
typecho模板制作代码收集
查看>>
Python学习笔记4:集合方法
查看>>
POJ - 3696 同余
查看>>
[随想感悟] 《归去来兮辞·并序》 赏析
查看>>
elasticsearch的监控脚本
查看>>
USACO 之 Section 1.3 Greedy Algorithm (已解决)
查看>>
数组排序
查看>>
51Nod 1090: 3个数和为0
查看>>
dos 操作显示 > nul 2>nul
查看>>
Lucene初级教程
查看>>
leetcode 205. Isomorphic Strings(哈希表)
查看>>
爬取校园新闻首页的新闻
查看>>
OpenStack学习系列-----第二篇 由一个错误看理解整个架构的重要性
查看>>
android 透明度
查看>>
安装mongodb到系统服务
查看>>