代码写了不到30分钟,改它用了几个小时。先说题意,给你一颗树,边上有权,两点间的路径上的路径的边权抑或起来就是路径的xor值,要求的是最大的这样的路径是多少。讲到树上的两点的xor,一个常用的手段就是随便选一个根,然后深搜记下每个点v到根的xor路径 w[v],那么两点x,y路径的xor就是w[x]^w[y].

深搜一发,问题转化为给你一个数组a,求a中哪两个数的抑或值最大。解决该问题的方法就是Trie树。

对每个权值由二进制高位到低位插到Trie树里,当要询问对于权值x最大的xor的时候,就需要从树上贪心的去匹配,譬如x的高位是1,那么我们就希望从Trie树上往0走,否则的话我们希望往1走,也就是尽可能使高位最大。这个在Trie树中是很容易实现的。在本题中n个数,最大是2^31-1,所以需要的节点的数量最多可以到到达32n。我们做的时候是询问一个数,插一个数,每次询问的复杂度也是O(32),所以总复杂度是O(32n)

这是Trie树的一个典型应用。

下面说说自己碰到的坑。首先是第一次写Trie树,当我新建结点的时候我忘了对左右儿子设NUll,导致出错。还有一些其余的细节错。最重要的是后来T了不知道多少发。最后发现是被卡邻接表了vector G[maxn]的写法会T, next的那种写法就过了。我想可能是初始化的时候G[i].clear()非常耗时的缘故吧。提醒了我一下邻接表的重要性。

#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<vector>
#define maxn 100050
using namespace std; struct Edge
{
int to;
int w;int next;
Edge(){}
Edge(int ti,int wi):to(ti),w(wi){}
}edges[2*maxn];
int etop;
int w[maxn+50];
int n;
int ans;
int first[maxn+20]; void addEdge(int u,int v,int w)
{
Edge &e=edges[etop++];
e.to=v;e.w=w;
e.next=first[u];first[u]=etop-1;
} void dfs(int u,int wht,int fa)
{
w[u]=wht;
for(int i=first[u];i!=-1;i=edges[i].next){
int v=edges[i].to;
if(v!=fa){
dfs(v,wht^edges[i].w,u);
}
}
} struct TrieNode
{
TrieNode *next[2];
}T[maxn*32],*Trie;
int top;
int bit[33];
const int maxSize=30; void insert(int x)
{
TrieNode *p=Trie;
for(int i=maxSize;i>=0;--i){
int indice=x&bit[i]? 1:0;
if(p->next[indice]!=NULL){
p=p->next[indice];
}
else{
p->next[indice]=&T[top++];
T[top-1].next[0]=T[top-1].next[1]=NULL;
p=p->next[indice];
}
}
} int find(int x)
{
TrieNode *p=Trie;int ret=0;
for(int i=maxSize;i>=0;--i){
int indice=x&bit[i]? 1:0;
if(p->next[indice^1]!=NULL){
ret+=bit[i];
p=p->next[indice^1];
}
else{
p=p->next[indice];
} }
return ret;
} int main()
{
bit[0]=1;
for(int i=1;i<=31;++i){
bit[i]=bit[i-1]*2;
}
while(cin>>n)
{
int u,v,ww;
memset(first,-1,sizeof(first));etop=0;
for(int i=0;i<n-1;++i){
scanf("%d%d%d",&u,&v,&ww);
addEdge(u,v,ww);
addEdge(v,u,ww);
}
dfs(0,0,-1);top=0;Trie=&T[top++];T[top-1].next[0]=T[top-1].next[1]=NULL;
insert(w[0]);ans=0;
for(int i=1;i<n;++i){
int tmp=find(w[i]);
ans=tmp>ans? tmp:ans;
insert(w[i]);
}
printf("%d\n",ans);
}
return 0;
}

POJ3764 The xor-longest path Trie树的更多相关文章

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

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

  2. Poj 3764 The xor-longest Path(Trie树+xor+贪心)

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

  3. 【bzoj1954】Pku3764 The xor-longest Path Trie树

    题目描述  给定一棵n个点的带权树,求树上最长的异或和路径 输入 The input contains several test cases. The first line of each test ...

  4. HDU 4825 Xor Sum (trie树处理异或)

    Xor Sum Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 132768/132768 K (Java/Others)Total S ...

  5. POJ 3764 The xor-longest Path trie树解决位运算贪心

    http://poj.org/problem?id=3764 题意 :  一颗树,每个边有个值,在树上找一条简单路径,使得这条路径上的边权异或值最大 先找到所有节点到一点的距离 , 显然dis( x ...

  6. HDU4825 Xor Sum(贪心+Trie树)

    Problem Description Zeus 和 Prometheus 做了一个游戏,Prometheus 给 Zeus 一个集合,集合中包含了N个正整数,随后 Prometheus 将向 Zeu ...

  7. The Xor-longest Path(trie树)

    题目: #10056. 「一本通 2.3 练习 5」The XOR-longest Path 解析: 做完#10051后就不是很难了 继续利用异或的性质有\(dis(u,v) = dis(1,u)\o ...

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

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

  9. Xor - Trie树

    题目描述 求一棵带边权的树的一条最大 Xor 路径的值.这里的"路径"不一定从根到叶子结点,中间一段路径只要满足条件也可以. 输入格式 第一行,一个整数 N ,表示一颗树有 N 个 ...

随机推荐

  1. ThinkPHP快速入门

    ThinkPHP快速入门 1.ThinkPHP自动生成 当我们部署完ThinkPHP框架后,其会自动生成Application文件夹,如下图所示: 2.自动生成细节分析 问题1:Application ...

  2. Codevs 1105 过河

     时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond  题目描述 Description 在河上有一座独木桥,一只青蛙想沿着独木桥从河的一侧跳到另一侧.在桥上有 ...

  3. java和javascript中this区别的浅探讨

    今天在学习javascript的时候碰到了this,感觉它跟java里的有点不一样.然后上网查了一下,参考了这篇文章,JavaScript中this关键字详解,发现它们之间的区别主要是这样: java ...

  4. Ubantu 安装 LAMP环境

    1.通过 apt-get update 命令从ubantu软件源中下载可安装软件的列表. 2.通过一条命令可以一次性的安装LAMP apt-get install apache2 php5 mysql ...

  5. Objective-C中字典的使用方法总结

    在Objective-C中提供了两个类来实现字典,即NSDictionary和NSMutableDictionary.其中,NSMutableDictionary是NSDictionary的子类,它继 ...

  6. linux 终端显示 -bash-4.1

    解决方法: cp /etc/skel/.bashrc /root/ cp /etc/skel/.bash_profile  /root/ 重新登陆就OK了

  7. pandas库学习笔记(二)DataFrame入门学习

    Pandas基本介绍——DataFrame入门学习 前篇文章中,小生初步介绍pandas库中的Series结构的创建与运算,今天小生继续“死磕自己”为大家介绍pandas库的另一种最为常见的数据结构D ...

  8. kdbchk: the amount of space used is not equal to block size

    一.对数据文件检查 注意:应该在关闭数据库模式下进行bbed的操作 [oracle@ora10 controlfile]$ dbv file=/u01/app/oracle/oradata/ORCL/ ...

  9. SQL多表连接

    在KS系统中分配好权限以后,在用户登录的时候就要通过用户查到角色,通过角色查到界面,界面又属于某个菜单,一共要查4个表.并且不能有重复的记录这个时候就用到了SQL的内连接.SQL的多表连接很方便,以前 ...

  10. js中typeof可以准确判断哪些变量类型

    typeof 运算符返回一个用来表示表达式的数据类型的字符串.  可能的字符串有:"number"."string"."boolean".& ...