The xor-longest Path

Description

In an edge-weighted tree, the xor-length of a path p is defined as the xor sum of the weights of edges on p:

⊕ is the xor operator.

We say a path the xor-longest path if it has the largest xor-length. Given an edge-weighted tree with n nodes, can you find the xor-longest path?  

Input

The input contains several test cases. The first line of each test case contains an integer n(1<=n<=100000), The following n-1 lines each contains three integers u(0 <= u < n),v(0 <= v < n),w(0 <= w < 2^31), which means there is an edge between node u and v of length w.

Output

For each test case output the xor-length of the xor-longest path.

Sample Input

4
0 1 3
1 2 4
1 3 6

Sample Output

7

Hint

The xor-longest path is 0->1->2, which has length 7 (=3 ⊕ 4)

题意:

给你一棵树,求树上异或和最大的路径。

题解:

这题之前索神讲过……所以我竟然还考虑了一会才写

首先看到异或我们不妨顺便总结一下它的性质:

  1. 自反性:x^0=x, x^x=0
  2. 结合性:a^b^c=a^(b^c)

 由这两个性质能组合出一个在OI中常用的技巧:a^b^a^c=b^c

也就是说两段相同的东西(可以是前缀,后缀,区间)异或起来就消掉了。

知道这个性质之后我们还知道一个模型:

对于一个数,想要在$n$个数中找到与它异或和最大的数,我们除了暴力,

也可以将每个数拆成二进制后视作一个字符串建立Trie树,这样就可以做到O(logn)查询。

那么我们再来看一下这道题:树上路径由于有多个点所以不能应用上面的方法。

这个时候应用第一个技巧我们可以发现:Sum(u,v)=Sum(1,u)^Sum(1,v)

那么多个点的路径异或和就转化成了两个点的前缀异或和。

然后直接写就好了。

代码:

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio> using namespace std;
#define MAXN 100005
#define MAXM 500005
#define INF 0x7fffffff
#define ll long long inline int read(){
int x=,f=;
char c=getchar();
for(;!isdigit(c);c=getchar())
if(c=='-')
f=-;
for(;isdigit(c);c=getchar())
x=x*+c-'';
return x*f;
} int N,cnt,hd[MAXN],cst[MAXM<<];
int to[MAXM<<],nxt[MAXM<<];
int num=,sum[MAXN],ch[MAXN*][]; inline void addedge(int u,int v,int w){
to[++cnt]=v,cst[cnt]=w,nxt[cnt]=hd[u],hd[u]=cnt;
to[++cnt]=u,cst[cnt]=w,nxt[cnt]=hd[v],hd[v]=cnt;
} inline void insert(int x){
for(int i=,u=;i>=;i--){
bool c=(x&(<<i))!=;
if(!ch[u][c]) ch[u][c]=++num;
u=ch[u][c];
}
} inline void dfs(int u,int fa,int s){
sum[u]=s; insert(s);
for(int i=hd[u];i;i=nxt[i]){
int v=to[i],w=cst[i];
if(v==fa) continue;
dfs(v,u,s^w);
}
return;
} inline int calc(int x){
int ans=,u=;
for(int i=;i>=;i--){
bool c=(x&(<<i))!=;
if(ch[u][c^]) ans+=(<<i),u=ch[u][c^];
else u=ch[u][c];
}
return ans;
} int main(){
N=read(); int ans=;
for(int i=;i<N;i++){
int u=read(),v=read(),w=read();
addedge(u,v,w);
}
dfs(,,);
for(int i=;i<=N;i++)
ans=max(ans,calc(sum[i]));
printf("%d\n",ans);
return ;
}

最新文章

  1. byte[] 转成图片方法
  2. Linux常用命令(二)
  3. Word Break
  4. Nginx密码验证 ngx_http_auth_basic_module模块
  5. 原生JS实现轮播+学前端的感受(防止走火入魔)
  6. 61.MII、RMII、GMII接口的详细介绍
  7. CSS滤镜详解
  8. 使用讯飞SDK,实现文字在线合成语音
  9. 房租管理小软件(七):flowlayoutPancel 中增加分类控
  10. hdu1016JAVA
  11. 对RecycleView的多种item布局的封装
  12. html表格合并(行,一排)
  13. MVC新语法匿名方法
  14. javascript: 常用操作
  15. .NET中的repeater简介及分页效果
  16. golang 在 windows 下编译出 linux 二进制可执行文件的软件套装合集 [go 1.7.3环境]
  17. 解决TOC与目录导航冲突问题
  18. 尚硅谷springboot学习11-占位符
  19. SQL Merge 语法 单表查询
  20. 深入解析ES6 更易于继承的类语法的使用

热门文章

  1. Java接口 详解(一)
  2. static语句块的执行时间
  3. 程序猿老公去米国参加 WWDC,顺便想带渡老婆蜜月,如何办签证?
  4. ubuntu关闭cups服务
  5. 单机 Oracle 11g(11.2.0.4)手动打补丁PSU(11.2.0.4.8)
  6. mysql建表练习
  7. java的动态代理原理
  8. [Forward]Improving Web App Performance With the Chrome DevTools Timeline and Profiles
  9. [hdu4311]Meeting point-1
  10. TypeScript完全解读(26课时)_汇总贴