建立字典树是异或的一种处理方法。

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:

$$_{xor}length(p)=\bigoplus _{e\in p}w(e)$$

$\bigoplus$ 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 \le u < n),v(0 \le v < n),w(0 \le 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 $latex \bigoplus$ 4)

题解:

    题目要求找一条路径使得这条路径上的每条边异或和最大。对于朴素算法我们可以预处理树上前缀异或和,通过求任意两点的LCA,并把两条路径再异或得到答案更新(异或是有结合律的)。这样的时间复杂度是$O(n^2\log n)$。

    如果看出异或就是异或的逆运算,也就是$x\bigoplus y\bigoplus y=x$,就可以知道,我们直接将两点的树上异或前缀和再次异或,就相当于消去了二者LCA以上的部分,得出的结果就是两者唯一路径上的异或和。LCA以上的部分实际上是异或了一遍又异或回来了。

    此时我们只要枚举两个点,让它们的前缀和相异或就可以了,时间复杂度为$O(n^2)$。但是$latex 100,000$的数据需要更加优化。

    我们可不可以先存下所有点的异或前缀和,然后枚举每个点,在$O(1)$或$O(\log n)$的时间复杂度内找出已经存下的点的前缀和中与当前点的前缀和异或和最大的来更新答案呢?

    尽管与一个数的异或不满足任何RMQ问题的解法,但是我们是不是可以贪心呐?对于一个二进制数,我们要使得一个数与它的异或值最大,就要按位从大到小尽可能不同。也就是贪心的思想,即$(10000000)_2>(01111111)_2$。

101001001 (1)
110100100 (2)
100110011 (3)

    因为(2)与(1)在第6位(最右边是第0位)就出现了不同,因此(1)跟(2)匹配是要比(3)优的。

    那我们要找到与一个数异或最大的,就可以把这个数给转成二进制,按位次从高到低建立字典树,深度越浅,贪心程度越大。因此贪心得出的结果总是唯一最优的。这里用了动态开点,不然找到了不存在的数,计算就会出现错误。

    这棵字典树也就是一棵二叉树,我们就要尽可能朝与当前位相反的地方走;如果没有相反的就只好顺着走了。并且因为每条链深度都是31的,所以不用担心访问到空节点。

Code:

#include<cstdio>
#include<cstring>
struct node
{
int down;
node *ls,*rs;
node()
{
ls=NULL;
rs=NULL;
}
void build(int x,int k)//开点的过程
{
if(k==-1)
return;
if((x>>k)&1)
{
if(!rs)
rs=new node();
rs->build(x,k-1);
}
else
{
if(!ls)
ls=new node();
ls->build(x,k-1);
}
}
int inv(int x,int k)//求尽可能多的相反能造成多少贡献
{
if(k<0)
return 0;
if((x>>k)&1)
{
if(ls)
return (1<<k)+ls->inv(x,k-1);
else
return rs->inv(x,k-1);
}
else
{
if(rs)
return (1<<k)+rs->inv(x,k-1);
else
return ls->inv(x,k-1);
}
}
}*root;
struct edge//建树
{
int n,v,nxt;
edge(int n,int nxt,int v)
{
this->n=n;
this->v=v;
this->nxt=nxt;
}
edge()
{
nxt=-1;
} }e[220000];
int head[100100],ecnt=-1;
void add(int from,int to,int v)
{
e[++ecnt]=edge(to,head[from],v);
head[from]=ecnt;
e[++ecnt]=edge(from,head[to],v);
head[to]=ecnt;
}
int sum[100100];
void dfs(int x,int from)
{
for(int i=head[x];~i;i=e[i].nxt)
if(e[i].n!=from)
{
sum[e[i].n]=(sum[x]^e[i].v);
dfs(e[i].n,x);
}
return;
}
int main()
{
root=new node();
memset(head,-1,sizeof(head));
int n,u,v,w;
scanf("%d",&n);
for(int i=1;i<n;++i)
{
scanf("%d%d%d",&u,&v,&w);
add(u,v,w);
}
sum[1]=0;
dfs(1,1);
for(int i=1;i<=n;++i)
root->build(sum[i],30);
int ans=0;
for(int i=1;i<=n;++i)
{
int tmp=root->inv(sum[i],30);
ans=ans>tmp?ans:tmp;
}
printf("%d\n",ans);
return 0;
}

  

【字典树】【树】【二进制】bzoj1954/POJ3764The xor-longest Path 题解的更多相关文章

  1. poj3764 The XOR Longest Path【dfs】【Trie树】

    The xor-longest Path Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 10038   Accepted:  ...

  2. 题解 bzoj1954【Pku3764 The xor – longest Path】

    做该题之前,至少要先会做这道题. 记 \(d[u]\) 表示 \(1\) 到 \(u\) 简单路径的异或和,该数组可以通过一次遍历求得. \(~\) 考虑 \(u\) 到 \(v\) 简单路径的异或和 ...

  3. 【转】B树、B-树、B+树、B*树、红黑树、 二叉排序树、trie树Double Array 字典查找树简介

    B  树 即二叉搜索树: 1.所有非叶子结点至多拥有两个儿子(Left和Right): 2.所有结点存储一个关键字: 3.非叶子结点的左指针指向小于其关键字的子树,右指针指向大于其关键字的子树: 如: ...

  4. CSU - 1551 Longest Increasing Subsequence Again —— 线段树/树状数组 + 前缀和&后缀和

    题目链接:http://acm.csu.edu.cn/csuoj/problemset/problem?pid=1551 题意: 给出一段序列, 删除其中一段连续的子序列(或者不删), 使得剩下的序列 ...

  5. 【BZOJ 3626】 [LNOI2014]LCA【在线+主席树+树剖】

    题目链接: TP 题解:   可能是我比较纱布,看不懂题解,只好自己想了…… 先附一个离线版本题解[Ivan] 我们考虑对于询问区间是可以差分的,然而这并没有什么卵用,然后考虑怎么统计答案. 首先LC ...

  6. 主席树+树链剖分——南昌邀请赛Distance on the tree

    学了差不多一星期的主席树+树链剖分,再来看这题发现其实是个板子题 一开始想复杂了,以为要用类似求树上第k大的树上差分思想来解决这道题,但其实树链上<=k的元素个数其实直接可以用树链剖分来求 具体 ...

  7. HDU 3333 Turing Tree 离线 线段树/树状数组 区间求和单点修改

    题意: 给一个数列,一些询问,问你$[l,r]$之间不同的数字之和 题解: 11年多校的题,现在属于"人尽皆知傻逼题" 核心思想在于: 对于一个询问$[x,R]$ 无论$x$是什么 ...

  8. acm 2015北京网络赛 F Couple Trees 主席树+树链剖分

    提交 题意:给了两棵树,他们的跟都是1,然后询问,u,v 表 示在第一棵树上在u点往根节点走 , 第二棵树在v点往根节点走,然后求他们能到达的最早的那个共同的点 解: 我们将第一棵树进行书链剖,然后第 ...

  9. BZOJ1146 [CTSC2008]网络管理Network 树链剖分 主席树 树状数组

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1146 题意概括 在一棵树上,每一个点一个权值. 有两种操作: 1.单点修改 2.询问两点之间的树链 ...

  10. 洛谷P3960 列队 NOIp2017 线段树/树状数组/splay

    正解:动态开点线段树 解题报告: 传送门! 因为最近学主席树的时候顺便get到了动态开点线段树?刚好想起来很久很久以前就想做结果一直麻油做的这题,,,所以就做下好了QAQ 然后说下,这题有很多种方法, ...

随机推荐

  1. ubuntu16.04 Mask_RCNN AlphaPose OpenPose Librealsense

    #############MaskRCNNcource activate flappbirdcd /home/luo/Desktop/MyFile/MaskRCNN/MyOwnMaskRCNN1/sa ...

  2. 使用clr 调用C#编写的dll中的方法的全解释

    使用clr 调用C#编写的dll中的方法的全解释1.数据库初始化:将下面这段代码直接在运行就可以初始化数据库了exec sp_configure 'show advanced options', '1 ...

  3. js数值和字符串比较的规则

    1.数值和字符串比较时 a.若字符串为数字字符串,则将字符串转为数字,再比较 b.若字符串不为数字字符串,则直接返回false,因为这里把字符串转为了NaN, 数字与NaN比较,都返回false

  4. Git全面教程

    Git全面教程 简介 Git分布式版本管理系统. Linus在1991年创建了开源的Linux,但是一直没有一个合适的版本管理工具,在2002年以前,世界各地的志愿者都是通过把源代码文件通过diff的 ...

  5. HttpUploader7-授权码配置

    1.1. 七牛云存储 配置方式: 1.配置授权码   2.配置云存储   3.配置空间名称   4.配置上传地址   1.2. 阿里云存储 配置方式: 1.填写授权码   2.配置云存储为阿里云   ...

  6. 【leetcode】Move Zeroes

    Move Zeroes 题目: Given an array nums, write a function to move all 0‘s to the end of it while maintai ...

  7. 关于spring”通配符的匹配很全面, 但无法找到元素 'context:component-scan' 的声明“的错误

    关于spring配置的问题 近日学习spring时遇到了这个问题: org.springframework.beans.factory.xml.XmlBeanDefinitionStoreExcept ...

  8. Codeforces 900C. Remove Extra One(暴力)

    You are given a permutation p of length n. Remove one element from permutation to make the number of ...

  9. DELPHI XE5 跨平台 Form ShowModal 官方示例

    Calling ShowModal as an Anonymous Method on All Platforms procedure THeaderFooterForm.btnPickClick(S ...

  10. 转换汉子首字母类 CreatChinaSpell

    public class CreatChinaSpell { public static string GetChineseFirstChar(string chineseStr) { StringB ...