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

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. PCL 常用小知识

    时间计算 pcl中计算程序运行时间有很多函数,其中利用控制台的时间计算 首先必须包含头文件 #include <pcl/console/time.h> #include <pcl/c ...

  2. PHP初级经典面试题目汇总

    17.isset.empty.is_null的区别 isset 判断变量是否定义或者是否为空 变量存在返回ture,否则返回false 变量定义不赋值返回false unset一个变量,返回false ...

  3. Django开发——集成的子框架django.contrib

    Django开发——集成的子框架django.contrib 2018年09月11日 19:32:42 Mrkang1314 阅读数:63  https://blog.csdn.net/mashaok ...

  4. asp.net服务器推送长连接

    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx. ...

  5. 第十二课 Actionlib(1)

    一\Actionlib概念 在ROS系统中,有时需发送请求给某个节点完成相应的任务,同时获得一个一个响应,这种情况下可以通过ROS服务来 完成;然而,在某些情况下,服务需要很长时间才能执行完,如让机器 ...

  6. [GO]切片和底层数组的关系

    package main import "fmt" func main() { a := [], , , , , , , , , } s1 := a[:] s1[] = fmt.P ...

  7. Robot Framework - 常用断言讲解

    RobotFramework带有丰富的系统关键,使用时无需导入,直接使用,为写自动化用例带来了极大的方便:不能停留在知道或者是会得程度,只有熟练使用各关键字,才能提升自动化用例的写作效率. 下面将逐个 ...

  8. VUE实战项目-数据转换之道

    前言 公司的这个项目从去年底启动.至今经历winform版本与当前的VUE两个版本,前后经历不足3个月的时间.从纯技术角度来看,推进速度都很优异.究其原因,大抵我们都是喜欢“偷懒”的程序员,把能封装. ...

  9. MVC下的cshtml和aspx页面

    MVC中的aspx页面是System.Web.Mvc.ViewPage类的实例. 表示将视图呈现为 Web 窗体页所需的属性和方法. 继承层次结构 System.Object System.Web.U ...

  10. WEB缓存初探

    WEB缓存初探 概念理解 缓存--缓存就是数据交换的缓冲区(称作Cache) 缓存 的作用说白了就是用来就近获取东西,比如我们会把已经拿到的常用的东西放在手边(与自己相对较近的地方),方便下次需要时去 ...