poj 3764 字典树

The xor-longest Path

Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 7332   Accepted: 1555

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)

Source

题意:

给出一棵树,求这棵树中的最大的异或路径。

代码:

//预处理出来每个点到根的异或值sxor,然后u,v之间的异或路径值就是sxor[u]^sxor[v],lca就消去了。然后把每个点的sxor值插入字典
//树(二进制字典树),枚举每个点贪心的找他的最大异或路径。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int MAXN=200000;
int head[MAXN*2+9],tot,sxor[MAXN*2+9],sz,nod[MAXN*2+9][2],ans;
struct Edge
{
    int to,w,next;
}edge[MAXN*4+9];
void init()
{
    memset(sxor,0,sizeof(sxor));
    memset(head,-1,sizeof(head));
    nod[0][0]=nod[0][1]=0;
    tot=0;
    sz=0;ans=0;
}
void add(int x,int y,int z)
{
    edge[tot].to=y;
    edge[tot].w=z;
    edge[tot].next=head[x];
    head[x]=tot++;
    edge[tot].to=x;
    edge[tot].w=z;
    edge[tot].next=head[y];
    head[y]=tot++;
}
void insert(int x)
{
    int rt=0;
    for(int i=30;i>=0;i--){
        int id=(x>>i)&1;
        if(nod[rt][id]==0){
            nod[rt][id]=++sz;
            nod[sz][0]=nod[sz][1]=0;
        }
        rt=nod[rt][id];
    }
}
void dfs(int x,int fa,int sum)
{
    for(int i=head[x];i!=-1;i=edge[i].next){
        int y=edge[i].to;
        if(y==fa) continue;
        sxor[y]=(sum^edge[i].w);
        dfs(y,x,sum^edge[i].w);
    }
}
void solve(int x)
{
    int sum=0,rt=0;
    for(int i=30;i>=0;i--){
        int id=(x>>i)&1;
        if(nod[rt][!id]){
            sum|=(1<<i);
            rt=nod[rt][!id];
        }else if(nod[rt][id]) rt=nod[rt][id];
        else break;
    }
    ans=max(ans,sum);
}
int main()
{
    int n;
    while(scanf("%d",&n)==1){
        int x,y,z;
        init();
        for(int i=1;i<n;i++){
            scanf("%d%d%d",&x,&y,&z);
            add(x,y,z);
        }
        dfs(0,-1,0);
        for(int i=0;i<n;i++){
            solve(sxor[i]);
            insert(sxor[i]);
        }
        printf("%d\n",ans);
    }
    return 0;
}
时间: 2024-08-08 11:19:09

poj 3764 字典树的相关文章

POJ 2503 字典树

这题记得以前是我们周赛的题,然后用的是map,也暴过了. 因为这两天要给大一的讲字典树,所以练练几道的代码,以防给大一搞晕了-- #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<map> #include<queue> #include<set> #include<cmath> #include

POJ 2418 字典树

题目链接:http://poj.org/problem?id=2418 题意:给定一堆树的名字,现在问你每一棵树[无重复]的出现的百分比,并按树名的字典序输出 思路:最简单的就是用map来写,关于字典树的解法,因为字典序的先序遍历是排序的,所以只需建好树后先序遍历一下树就可以满足题目要求的输出方式了. 坑点:树名会出现空格,而且题目也没说明可能出现的字符集合,所以树的孩子结点要有128个. G++无限WA换C++就能AC,这个无解... map: #define _CRT_SECURE_NO_D

POJ 2418 字典树 or map

e...... DESCRIPTION: 给你许多种名字可以重复.要求你统计每种名字的比例.按照字典序输出每种名字及其所占比例.可以用字典树快速存储,输出大量字符串. 也可以用map.但是.map不太熟.输出好烦.为什么key值是字符数组的时候只能用Cout不能是printf.也不能用各种字符数组的函数呢.什么鬼!T_T用完C++还有编译器C++WA.G++AC.>_<. 附代码:map: #include<stdio.h>#include<string.h>#incl

POJ 2001 字典树(入门题)

#include<cstdio> #include<algorithm> #include<iostream> #include<cstring> #include<vector> #include<stack> #include<cmath> #include<queue> #include<map> using namespace std; struct Node { int c; int ne

POJ 2513 字典树+并查集+欧拉路径

Description: 给定一些木棒,木棒两端都涂上颜色,求是否能将木棒首尾相接,连成一条直线,要求不同木棒相接的一边必须是相同颜色的. 解题思路: 可以用图论中欧拉路的知识来解这道题,首先可以把木棒两端看成节点,把木棒看成边,这样相同的颜色就是同一个节点 问题便转化为: 给定一个图,是否存在“一笔画”经过涂中每一点,以及经过每一边一次. 这样就是求图中是否存在欧拉路Euler-Path.(我才知道这个就是欧拉路径...T_T) 由图论知识可以知道,无向图存在欧拉路的充要条件为: ①    

POJ 2513(字典树hash+并查集+欧拉通路)

Colored Sticks Time Limit: 5000MS   Memory Limit: 128000K Total Submissions: 31015   Accepted: 8180 Description You are given a bunch of wooden sticks. Each endpoint of each stick is colored with some color. Is it possible to align the sticks in a st

poj 3764 The xor-longest Path(字典树)

题目链接:poj 3764 The xor-longest Path 题目大意:给定一棵树,每条边上有一个权值,找出一条路径,使得路径上权值的亦或和最大. 解题思路:dfs一遍,预处理出每个节点到根节点路径的亦或和rec,那么任意路径均可以表示rec[a] ^ rec[b],所以问题 就转换成在一些数中选出两个数亦或和最大,那么就建立字典树查询即可. #include <cstdio> #include <cstring> #include <algorithm> us

ACM学习历程—POJ 3764 The xor-longest Path(xor &amp;&amp; 字典树 &amp;&amp; 贪心)

题目链接:http://poj.org/problem?id=3764 题目大意是在树上求一条路径,使得xor和最大. 由于是在树上,所以两个结点之间应有唯一路径. 而xor(u, v) = xor(0, u)^xor(0, v). 所以如果预处理出0结点到所有结点的xor路径和,问题就转换成了求n个数中取出两个数,使得xor最大. 这个之前用字典树处理过类似问题. 代码: #include <iostream> #include <cstdio> #include <cst

POJ 3764 - The xor-longest Path - [DFS+字典树变形]

题目链接:http://poj.org/problem?id=3764 Time Limit: 2000MS Memory Limit: 65536K 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)$ $\oplus$