#10056. 「一本通 2.3 练习 5」The XOR-longest Path

题目描述

原题来自:POJ 3764

给定一棵 nnn 个点的带权树,求树上最长的异或和路径。

输入格式

第一行一个整数 nnn,接下来 n−1n-1n−1 行每行三个整数 u,v,wu,v,wu,v,w,表示 u,vu,vu,v 之间有一条长度为 www 的边。

输出格式

输出一行一个整数,表示答案。

样例

样例输入

  1. 4
  2. 1 2 3
  3. 2 3 4
  4. 2 4 6

样例输出

  1. 7

样例解释

最长的异或和路径是 1→2→31\to 2\to 31→2→3 ,它的长度是 3⨁4=73 \bigoplus 4=73⨁4=7。

注意:结点下标从 111 开始到 NNN。

注:x⨁yx \bigoplus yx⨁y 表示 xxx 与 yyy 按位异或。

数据范围与提示

对于 100%100\%100% 的数据,1≤n≤105,1≤u,v≤n,0≤w<2311\le n\le 10^5,1\le u, v \le n,0 \le w < 2^{31}1≤n≤10​5​​,1≤u,v≤n,0≤w<2​31​​

题解

首先对于树上两点路径的异或值,可以用一个树上前缀和维护。

记$sum[x]$为$x$到祖先的异或和。

由于异或有:$a ⨁ a = 0$

所以如下图,在$sum[u] ⨁ sum[v]$时,lca以上的屎色线已经被消掉了。

所以$ans=sum[u] ⨁ sum[v]$

问题转化为:有1e5个数,要求其中两数异或的最大值。

于是变为「LOJ#10050」「一本通 2.3 例 2」The XOR Largest Pair (Trie

于是这道题就可以由两道看起来离得很远的题拼起来而成了。

  1. 编号 题目 状态 分数 总时间 内存 代码 / 答案文件 提交者 提交时间
  2. # #. 「一本通 2.3 练习 」The XOR-longest Path Accepted ms KiB C++ / 1.8 K qwerta -- ::
  3.  
  4. #include<iostream>
  5. #include<cstring>
  6. #include<cstdio>
  7. #include<cmath>
  8. using namespace std;
  9. inline int read()
  10. {
  11. char ch=getchar();
  12. int x=;
  13. while(!isdigit(ch))ch=getchar();
  14. while(isdigit(ch)){x=x*+ch-'';ch=getchar();}
  15. return x;
  16. }
  17. const int MAXN=1e5+;
  18. struct emm{
  19. int e,f,v;
  20. }a[*MAXN];//用来建树
  21. int h[MAXN];
  22. int tot=;
  23. void con(int x,int y,int l)//连树边
  24. {
  25. a[++tot].f=h[x];
  26. h[x]=tot;
  27. a[tot].e=y;
  28. a[tot].v=l;
  29. a[++tot].f=h[y];
  30. h[y]=tot;
  31. a[tot].e=x;
  32. a[tot].v=l;
  33. return;
  34. }
  35. int d[MAXN],w[MAXN];//记深度和前缀和
  36. void dfs(int x)//dfs遍历树
  37. {
  38. for(int i=h[x];i;i=a[i].f)
  39. if(!d[a[i].e])
  40. {
  41. w[a[i].e]=(w[x] xor a[i].v);
  42. d[a[i].e]=d[x]+;
  43. dfs(a[i].e);
  44. }
  45. return;
  46. }
  47. struct ahh{
  48. int nxt[];
  49. }tr[];//Trie树
  50. int cnt=;
  51. int b[];//用来按位拆分
  52. void add(int x)
  53. {
  54. int j=-;
  55. memset(b,,sizeof(b));
  56. while(x)//拆二进制
  57. {
  58. b[++j]=x&;
  59. x>>=;
  60. }
  61. int k=;
  62. for(int j=;j>=;--j)
  63. {
  64. if(!tr[k].nxt[b[j]])
  65. tr[k].nxt[b[j]]=++cnt;
  66. k=tr[k].nxt[b[j]];
  67. }
  68. return;
  69. }
  70. long long find(int x)//返回与x异或的最大结果
  71. {
  72. int j=-;
  73. memset(b,,sizeof(b));
  74. while(x)
  75. {
  76. b[++j]=x&;
  77. x>>=;
  78. }
  79. long long now=;
  80. int k=;
  81. for(int j=;j>=;--j)
  82. {
  83. if(tr[k].nxt[-b[j]])//尽量往不一样的走
  84. {
  85. now+=(<<j);
  86. k=tr[k].nxt[-b[j]];
  87. }
  88. else k=tr[k].nxt[b[j]];
  89. }
  90. return now;
  91. }
  92. int main()
  93. {
  94. //freopen("a.in","r",stdin);
  95. int n=read();
  96. for(int i=;i<n;++i)
  97. {
  98. int u=read(),v=read(),w=read();
  99. con(u,v,w);//连树边
  100. }
  101. int s=min(,n);
  102. d[s]=;
  103. dfs(s);
  104. long long ans=;
  105. for(int i=;i<=n;++i)
  106. add(w[i]);//加前缀和
  107. for(int i=;i<=n;++i)
  108. ans=max(ans,find(w[i]));//记录答案
  109. cout<<ans;
  110. return ;
  111. }

「LOJ#10056」「一本通 2.3 练习 5」The XOR-longest Path (Trie的更多相关文章

  1. 「LOJ#10051」「一本通 2.3 例 3」Nikitosh 和异或(Trie

    题目描述 原题来自:CODECHEF September Challenge 2015 REBXOR 1​​≤r​1​​<l​2​​≤r​2​​≤N,x⨁yx\bigoplus yx⨁y 表示 ...

  2. LOJ#10117. 「一本通 4.1 练习 2」简单题

    LOJ#10117. 「一本通 4.1 练习 2」简单题 题目描述 题目来源:$CQOI 2006$ 有一个$n$个元素的数组,每个元素初始均为$0$.有$m$条指令,要么让其中一段连续序列数字反转— ...

  3. LOJ#10064. 「一本通 3.1 例 1」黑暗城堡

    LOJ#10064. 「一本通 3.1 例 1」黑暗城堡 题目描述 你知道黑暗城堡有$N$个房间,$M$条可以制造的双向通道,以及每条通道的长度. 城堡是树形的并且满足下面的条件: 设$D_i$为如果 ...

  4. LOJ #10131 「一本通 4.4 例 2」暗的连锁

    LOJ #10131 「一本通 4.4 例 2」暗的连锁 给一棵 \(n\) 个点的树加上 \(m\) 条非树边 , 现在需要断开一条树边和一条非树边使得图不连通 , 求方案数 . $n \le 10 ...

  5. 「LOJ#10042」「一本通 2.1 练习 8」收集雪花 (map

    题目描述 不同的雪花往往有不同的形状.在北方的同学想将雪花收集起来,作为礼物送给在南方的同学们.一共有 n 个时刻,给出每个时刻下落雪花的形状,用不同的整数表示不同的形状.在收集的过程中,同学们不希望 ...

  6. 「LOJ#10043」「一本通 2.2 例 1」剪花布条 (KMP

    题目描述 原题来自:HDU 2087 一块花布条,里面有些图案,另有一块直接可用的小饰条,里面也有一些图案.对于给定的花布条和小饰条,计算一下能从花布条中尽可能剪出几块小饰条来呢? 输入格式 输入数据 ...

  7. 「LOJ#10015」「一本通 1.2 练习 2」扩散(并查集

    题目描述 一个点每过一个单位时间就会向 444 个方向扩散一个距离,如图所示:两个点 a .b 连通,记作 e(a,b),当且仅当 a .b的扩散区域有公共部分.连通块的定义是块内的任意两个点 u.v ...

  8. #10042. 「一本通 2.1 练习 8」收集雪花 || 离散化 || 双指针法 || C++ || LOJ

    题目:#10042. 「一本通 2.1 练习 8」收集雪花 看到网上没有这道题的题解,所以写一下. 要标记数字是否存在,看到x<=1e9,所以考虑用离散化,然后开一个last数组,last[i] ...

  9. 【LOJ#6066】「2017 山东一轮集训 Day3」第二题(哈希,二分)

    [LOJ#6066]「2017 山东一轮集训 Day3」第二题(哈希,二分) 题面 LOJ 题解 要哈希是很显然的,那么就考虑哈希什么... 要找一个东西可以表示一棵树,所以我们找到了括号序列. 那么 ...

随机推荐

  1. opencv3.3.1 opencv_contribut 3.3.1 git 20180117最新版的在ubuntu1604上的编译

    过程: 1.  git  clone  ...   contribut 2. git  clone  ...  opencv 3.  git  checkout  -b     v3.3.1 4 gi ...

  2. 【BZOJ3924】[Zjoi2015]幻想乡战略游戏 动态树分治

    [BZOJ3924][Zjoi2015]幻想乡战略游戏 Description 傲娇少女幽香正在玩一个非常有趣的战略类游戏,本来这个游戏的地图其实还不算太大,幽香还能管得过来,但是不知道为什么现在的网 ...

  3. EasyPlayerPro(Windows)流媒体播放器开发之接口设计

    EasyPlayerPro(windows)接口说明如下: EasyPlayerPro_Open 说明:打开一个媒体流或者媒体文件进行播放,同时返回一个 player 对象指针 参数说明: fileU ...

  4. 2017-2018-1 20179209《Linux内核原理与分析》第四周作业

    本周学习内容为<跟踪分析MenuOS简单linux系统的启动过程>和教材中的进程调度及内核数据结构. 一.跟踪分析Linux内核的启动过程 这个实验我是在实验楼环境中完成的,最初想在自己的 ...

  5. BZOJ2328: [HNOI2011]赛车游戏

    BZOJ2328: [HNOI2011]赛车游戏 Description 题解Here! 一开始被题面那一长串的描述吓到了,一直没敢做... 然后尝试着硬着头皮读懂题面. 然后...这不是贪心么??? ...

  6. SAP 第四代增强-BTE

    第四代BTE实例详解:http://blog.csdn.net/wbin9752/article/details/7954922 第三代增强(BADI实例详解) :http://blog.csdn.n ...

  7. SAP-财务会计

    [转自 http://blog.itpub.net/195776/viewspace-1023913/] 一.FI组织架构1主数据1.1总帐科目1.2帐户组.1.3统驭科目1.4 总帐未清项管理2 凭 ...

  8. 友盟分享到微信的几点备忘(IOS)

    1.下载最新的友盟分享版本,参考友盟官方的demo 2.注册微信开放平台用户,不是公众平台,注册应用 3.参考文档和demo,加入sdk包和相应的lib 4.在plist加入URL types.URL ...

  9. PAT 天梯赛 L3-008. 喊山 【BFS】

    题目链接 https://www.patest.cn/contests/gplt/L3-008 思路 因为 每个山头 最多有两个 能听到它的 临近山头 那么 我们就可以 给每个 山头 都 分配 最多两 ...

  10. PAT 甲级 1116. Come on! Let's C (20) 【循环判断】

    题目链接 https://www.patest.cn/contests/pat-a-practise/1116 思路 注意一个细节 如果没有本来 ID 的 后来又查了这个ID 不是输出 checked ...