洛谷P4551 最长异或路径 trie
题目描述
给定一棵\(n\)个点的带权树,结点下标从\(1\)开始到\(N\)。寻找树中找两个结点,求最长的异或路径。
异或路径指的是指两个结点之间唯一路径上的所有边权的异或。
输入格式
第一行一个整数\(N\),表示点数。
接下来 \(n−1\) 行,给出 \(u\),\(v\),\(w\) ,分别表示树上的 \(u\) 点和 \(v\) 点有连边,边的权值是 \(w\)。
输出格式
一行,一个整数表示答案。
输入输出样例
输入 #1
4
1 2 3
2 3 4
2 4 6
输出 #1复制
7
说明/提示
最长异或序列是1-2-3,答案是 7 (=3 ⊕ 4)
数据范围
\(1\le n \le 100000;0 < u,v \le n;0 \le w < 2^{31}\)
分析
先利用xor的性质:\(x \oplus y \oplus y=x\),提示我们只需要一遍电风扇dfs计算所有点到根节点(随便用1来当根节点)的\(xor\)路径即可。那么现在就可以\(O(n^2)\)做这道题了。
当然\(O(n^2)\)过\(10^5\)是不可能的(可以一试嘿
考虑用\(trie\)进行优化。
设\(f_i\)为\(i\)号节点到根节点的\(xor\)路径,对于每一个\(f_i\)直接插入\(0/1trie\),查询时从高位到低位贪心:
- 如果当前节点存在一个与要查询的\(f_i\)的这一位相反的儿子,那么就走向这一个节点,\(xor\)值的该位赋为一。
- 反之走向另一个节点,因为这一层走的节点与\(f_i\)的这一位相同,相同的值\(xor=0\)。
那么只要从每一个点进行一遍查询,即可查询到从这个点出发能够得到的最大\(xor\)路径。
取最大值即可。
Code
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<queue>
#include<vector>
#define IL inline
#define re register
#define LL long long
#define ULL unsigned long long
#define re register
#define debug printf("Now is %d\n",__LINE__);
using namespace std;
template<class T>inline void read(T&x)
{
char ch=getchar();
while(!isdigit(ch))ch=getchar();
x=ch-'0';ch=getchar();
while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
}
inline int read()
{
int x=0;
char ch=getchar();
while(!isdigit(ch))ch=getchar();
x=ch-'0';ch=getchar();
while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
return x;
}
int G[55];
template<class T>inline void write(T x)
{
int g=0;
if(x<0) x=-x,putchar('-');
do{G[++g]=x%10;x/=10;}while(x);
for(re int i=g;i>=1;--i)putchar('0'+G[i]);putchar('\n');
}
int n;
int head[200010],ver[200010],nxt[200010],w[200010];
int cnt;
void insert(int a,int b,int c)
{
nxt[++cnt]=head[a];
head[a]=cnt;
ver[cnt]=b;
w[cnt]=c;
nxt[++cnt]=head[b];
head[b]=cnt;
ver[cnt]=a;
w[cnt]=c;
}
//dfs
int f[100010];
void dfs(int x,int now,int fa)
{
f[x]=now;
for(int i=head[x];i;i=nxt[i])
{
if(ver[i]==fa) continue;
dfs(ver[i],now^w[i],x);
}
}
//trie
int trie[5000010][2];
int trie_cnt;
void insert(int x)
{
int now=0;
for(int i=31;i>=0;i--)
{
if(!trie[now][(x>>i)&1]) trie[now][(x>>i)&1]=++trie_cnt;
now=trie[now][(x>>i)&1];
}
}
int ask(int x)
{
int now=0,res=0;
for(int i=31;i>=0;i--)
{
bool y=(x>>i)&1;
if(trie[now][!y]) now=trie[now][!y],res+=1<<i;
else now=trie[now][y];
}
return res;
}
int main()
{
n=read();
for(int i=1,a,b,c;i<n;i++)
{
a=read();
b=read();
c=read();
insert(a,b,c);
}
dfs(1,0,0);
for(int i=1;i<=n;i++) insert(f[i]);
int ans=0;
for(int i=1;i<=n;i++) ans=max(ans,ask(f[i]));
cout<<ans;
return 0;
}
小结
过了样例,但是第一遍写的时候忘记写\(ask\)中的那一个else
了!导致调了半天都不知道哪里错了,叫Tringmo过来一看他就发现了。
/kk
洛谷P4551 最长异或路径 trie的更多相关文章
- 洛谷 P4551 最长异或路径
题目描述 给定一棵 nn 个点的带权树,结点下标从 11 开始到 NN .寻找树中找两个结点,求最长的异或路径. 异或路径指的是指两个结点之间唯一路径上的所有节点权值的异或. 输入输出格式 输入格式: ...
- 洛谷P4551 最长异或路径
传送门:https://www.luogu.org/problem/show?pid=4551 在看这道题之前,我们应懂这道题怎么做:给定n个数和一个数m,求m和哪一个数的异或值最大. 一种很不错的做 ...
- 2018.10.26 洛谷P4551 最长异或路径(01trie)
传送门 直接把每个点到根节点的异或距离插入01trie. 然后枚举每个点在01trie上匹配来更新答案就行了. 代码: #include<iostream> #include<cst ...
- [luogu] P4551 最长异或路径(贪心)
P4551 最长异或路径 题目描述 给定一棵\(n\)个点的带权树,结点下标从\(1\)开始到\(N\).寻找树中找两个结点,求最长的异或路径. 异或路径指的是指两个结点之间唯一路径上的所有边权的异或 ...
- P4551 最长异或路径
题目描述 给定一棵 nnn 个点的带权树,结点下标从 111 开始到 NNN .寻找树中找两个结点,求最长的异或路径. 异或路径指的是指两个结点之间唯一路径上的所有边权的异或. 输入输出格式 输入格式 ...
- P4551 最长异或路径 (01字典树,异或前缀和)
题目描述 给定一棵 n 个点的带权树,结点下标从 1 开始到 N .寻找树中找两个结点,求最长的异或路径. 异或路径指的是指两个结点之间唯一路径上的所有边权的异或. 输入输出格式 输入格式: 第一行一 ...
- Luogu P4551 最长异或路径
题目链接 \(Click\) \(Here\) \(01Trie\)好题裸题. 取节点\(1\)为根节点,向下扫每一个点从根节点到它路径上的异或和,我们可以得到一个\(sumx[u]\). 现在路径异 ...
- Luogu P4551 最长异或路径 01trie
做一个树上前缀异或和,然后把前缀和插到$01trie$里,然后再对每一个前缀异或和整个查一遍,在树上从高位向低位贪心,按位优先选择不同的,就能贪出最大的答案. #include<cstdio&g ...
- luoguP4551最长异或路径
P4551最长异或路径 链接 luogu 思路 从\(1\)开始\(dfs\)求出\(xor\)路径.然后根据性质\(x\)到\(y\)的\(xor\)路径就是\(xo[x]^xo[y]\) 代码 # ...
- 【ybt高效进阶2-4-3】【luogu P4551】最长异或路径
最长异或路径 题目链接:ybt高效进阶2-4-3 / luogu P4551 题目大意 给定一棵 n 个点的带权树,结点下标从 1 开始到 N.寻找树中找两个结点,求最长的异或路径. 异或路径指的是指 ...
随机推荐
- 【Hypermesh】TetraMesh Panel 常用选项详解
结合Hypermesh 2020 帮助文档和自己的一点使用经验,整理了这个博客.
- 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
大家好,我是小康.今天我们来聊一个藏在C++标准库中的"定时炸弹",它看起来人畜无害,但却坑了无数C++程序员. 前言:当你以为自己用的是vector,结果却不是 嘿,各位码农兄弟 ...
- httprunner 断言报错 expect_value 和check_value类型不一致
csv 源码 drillCode,drillName,code,msg y500,牙轮500,200,操作成功 YL201,牙轮201,500,牙轮编号已存在 运行后报错 E httprunner.e ...
- 谜一般的js,迷一般的console
问题的来源,是关于事件对象的currentTarget的讨论,currentTarget是什么,嗯,很简单就是绑定了监听函数,并且当前监听函数正在执行的那个dom元素.本着踏实,实事求是,严以律己的态 ...
- 几个技巧,教你去除文章的 AI 味!
最近有不少朋友在利用 AI 写毕业设计论文,几秒钟一篇文章就刷出来的,爽的飞起. 结果万万没想到,人家论文查重服务也升级了,是不是用 AI 写的论文大概率都能被查出来... 这可如何是好啊?救救我救救 ...
- 『Plotly实战指南』--柱状图绘制基础篇
柱状图作为最基础的数据可视化形式之一,能直观展示不同类别数据的对比关系,适用于一下的场景: 比较不同类别之间的数据大小,如不同产品的销售额对比. 展示数据的分布情况,如各年龄段的人口数量分布. 分析时 ...
- BUUCTF---佛说:只能四天
题目 尊即寂修我劫修如婆愍闍嚤婆莊愍耨羅嚴是喼婆斯吶眾喼修迦慧迦嚩喼斯願嚤摩隸所迦摩吽即塞願修咒莊波斯訶喃壽祗僧若即亦嘇蜜迦須色喼羅囉咒諦若陀喃慧愍夷羅波若劫蜜斯哆咒塞隸蜜波哆咤慧聞亦吽念彌諸嘚嚴諦咒 ...
- BUUCTF---unencode
1.题目 2.知识 UUENCODE是将二进制文件转换为文本文件的过程,转换后的文件可以通过纯文本e-mail进行传输,在接收方对该文件进行uudecode,即将其转换为初始的二进制文件. 3.解题 ...
- 【Java】操作数据库
工具: eclipse MySQL Navicat for MySQL MySQL 连接驱动:mysql-connector-java-5.0.4-bin.jar SQL 代码 CREATE TABL ...
- 【软件】基于JSP和Bootstrap的潇湘博客平台
潇湘博客平台 XiaoXiangBlog 说明 Eclipse 项目 - Version: 2020-06 (4.16.0). JDK8. 潇湘博客(XiaoXiangBlog) 一个简单的Java ...