早就听过用字典树求异或最大值,然而没做过。发现一碰到异或的题就GG,而且因为以前做过的一道类似的题(事实上并不类似)限制了思路,蠢啊= =。

题意:一棵带权的树,求任意两点间路径异或的最大值。

题解:设xor(a,b)是求a,b间路径的异或值,那么xor(a,b)=xor(root,a)^xor(root,b)。因为如果LCA(a,b)==root时结论显然成立,不然的话就会有重复走过的部分,但是异或有性质x^x=0,所以LCA(a,b)!=root结论依然成立。

这样题目就很简单了。对每一个xor(root,i)(0<i<n)建立trie,因为每个数转成二进制都是一个01组成的字符串,用来建立trie。然后对每一个xor(root,i)在trie查询最大值就好了。

#include <vector>
#include <list>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cstring>
#define pk printf("lalala");
#define ppp(x) printf("%d\n", x)
using namespace std;
#define PI acos(-1.0)
#define EXP exp(1.0)
#define EPS 1E-6
#define clr(x,c) memset(x,c,sizeof(x)) const int KIND = ;
const int MAXN = ;
const int N = ;
int cnt_node; struct node{
node* nt[KIND];
void init(){
memset(nt, , sizeof(nt));
}
} Heap[MAXN];
node *root;
int Xor[N]; inline node* new_node()
{
Heap[cnt_node].init();
return &Heap[cnt_node++];
} void insert(node* root, int *str)
{
for(int i = ; i <= ; ++i){
int ch = str[i];
if(root->nt[ch] == NULL)
root->nt[ch] = new_node();
root = root->nt[ch];
}
} int count(node* root, int *str)
{
int ans = ;
for(int i = ; i <= ; ++i){
int ch = str[i];
int need = (ch ^ );
if(root->nt[need] == NULL) {
root = root->nt[ch];
} else {
root = root->nt[need];
ans += ( << ( - i));
}
}
return ans;
} struct Edge {
int to;
int w;
int next;
} edge[N * ]; int cnt_edge;
int head[N]; void add_edge(int u, int v, int w)
{
edge[cnt_edge].to = v;
edge[cnt_edge].w = w;
edge[cnt_edge].next = head[u];
head[u] = cnt_edge++;
} void dfs(int u, int fa, int val)
{
Xor[u] = val;
for (int i = head[u]; i != -; i = edge[i].next) {
int v = edge[i].to;
int w = edge[i].w;
if (v == fa) continue;
dfs(v, u, val^w);
}
} int str[N][]; int main()
{
int n;
while (~scanf("%d",&n)) {
clr(head, -);
cnt_edge = ;
cnt_node = ;
root = new_node();
int u, v, w;
for (int i = ; i < n; ++i) {
scanf("%d%d%d",&u, &v, &w);
add_edge(u, v, w);
add_edge(v, u, w);
}
dfs(, -, );
//for (int i = 0; i < n; ++i) printf("%d ", Xor[i]); printf("\n");
int ans = ;
for (int i = ; i < n; ++i) {
int idx = ;
for (int b = ; b >= ; --b) {
str[i][idx++] = Xor[i] & ( << b) ? : ;
}
//for (int j = 0; j < idx; ++j) printf("%d ", str[i][j]); printf("\n");
insert(root, str[i]);
}
for (int i = ; i < n; ++i) {
ans = max(ans, count(root, str[i]));
}
printf("%d\n", ans);
}
return ;
}

POJ 3764 (异或+字典树)的更多相关文章

  1. POJ 2001 Shortest Prefixes(字典树)

    题目地址:POJ 2001 考察的字典树,利用的是建树时将每个点仅仅要走过就累加.最后从根节点開始遍历,当遍历到仅仅有1次走过的时候,就说明这个地方是最短的独立前缀.然后记录下长度,输出就可以. 代码 ...

  2. poj 1204 Word Puzzles(字典树)

    题目链接:http://poj.org/problem?id=1204 思路分析:由于题目数据较弱,使用暴力搜索:对于所有查找的单词建立一棵字典树,在图中的每个坐标,往8个方向搜索查找即可: 需要注意 ...

  3. poj 1056 IMMEDIATE DECODABILITY 字典树

    题目链接:http://poj.org/problem?id=1056 思路: 字典树的简单应用,就是判断当前所有的单词中有木有一个是另一个的前缀,直接套用模板再在Tire定义中加一个bool类型的变 ...

  4. POJ 2408 - Anagram Groups - [字典树]

    题目链接:http://poj.org/problem?id=2408 World-renowned Prof. A. N. Agram's current research deals with l ...

  5. POJ 1816 - Wild Words - [字典树+DFS]

    题目链接: http://poj.org/problem?id=1816 http://bailian.openjudge.cn/practice/1816?lang=en_US Time Limit ...

  6. nyoj 163 Phone List(动态字典树<trie>) poj Phone List (静态字典树<trie>)

    Phone List 时间限制:1000 ms  |  内存限制:65535 KB 难度:4   描述 Given a list of phone numbers, determine if it i ...

  7. poj 2503:Babelfish(字典树,经典题,字典翻译)

    Babelfish Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 30816   Accepted: 13283 Descr ...

  8. poj 2513 连接火柴 字典树+欧拉通路 好题

    Colored Sticks Time Limit: 5000MS   Memory Limit: 128000K Total Submissions: 27134   Accepted: 7186 ...

  9. POJ 1002 487-3279(字典树/map映射)

    487-3279 Time Limit: 2000MS        Memory Limit: 65536K Total Submissions: 309257        Accepted: 5 ...

随机推荐

  1. 谈 DevOps 自动化时,也应该考虑到 SOX 等法案

    [编者按]作者 Aaron Volkmann 是 CERT Division 高级研究员,在本文中,他对 DevOps 自动化违反 SOX 法案进行了阐述.同时,也简单的提出了如何通过 CI 来避免这 ...

  2. 5.查找最小的k个元素(数组)

    题目: 输入n个整数,输出其中最小的k个,例如输入1,2,3,4,5,6,7,8这8个数,则最小的4个是1,2,3,4(输出不要求有序) 解: 利用快速排序的partition,算导上求第k大数的思想 ...

  3. 李洪强iOS开发之静态库

    iOS开发拓展篇—静态库 一.简单介绍 1.什么是库? 库是程序代码的集合,是共享程序代码的一种方式 2.库的分类 根据源代码的公开情况,库可以分为2种类型 (1)开源库 公开源代码,能看到具体实现 ...

  4. cocos2d-x 添加 libLocalStorage 库...

    说明:由于libLocalStorage底层是用sqlite实现的,所以要先按上面官方提供的集成sqlite的文档,将sqlite添加到项目中. 重点还是android的编译配置,加粗的是需要增加的配 ...

  5. js 中多维数组的深拷贝的多种实现方式

    因为javascript分原始类型与引用类型(与java.c#类似).Array是引用类型,所以直接用=号赋值的话,只是把源数组的地址(或叫指针)赋值给目的数组,并没有实现数组的数据的拷贝.另外对一维 ...

  6. ArcGIS学习记录—KMZ KML与SHP文件互相转换

      1.在google earth中绘制边界  工具栏中选择"Add Polygon".随意绘制一个多边形.  右击添加的图层名(左侧)保存位置为,选择保存为kmz或kml文件.  ...

  7. Agri Net POJ1258 && Constructing Roads POJ2421

    题意,在给出的图中,使用最小花费的边,使这个图仍然连通. #include <cstdio> #include <algorithm> #include <cstring ...

  8. 217. Contains Duplicate

    题目: Given an array of integers, find if the array contains any duplicates. Your function should retu ...

  9. python学习笔记三--字典的使用

    一.基本使用: 1. 赋值:{key:value} 1.1 与列表相同处:会改变索引(键)相关联的值的改变 1.2 与列表不同处:不用考虑值的长度,而列表是有序的需要考虑末尾偏移量,超过末尾偏移量的会 ...

  10. while ((ch = getchar()) != EOF)中ch定义为char还是int型?cin、scanf等如何结束键盘输入

    2013-07-09 18:55:42 EOF是文件的结束符,具体可以作为文本文件的结束符,也可以作为键盘输入char类型数据时的结束符.对于不同的系统,EOF的定义可能不同,一般定义为-1.因为ch ...