Poj The xor-longest Path 经典题 Trie求n个数中任意两个异或最大值

Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 5646   Accepted: 1226

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)

题意:给出一颗n个节点的边权树,求一条路径(u,v),使得路径上的边的权值异或值最大

思路:我们可以先0为根,求出其他节点i到根的路径的边权异或值d[i],对于u,v之间路径的边权异或结果就是d[u]^d[v], 那么问题转化为给出n个数,求任意两个异或的最大值

把每一个数以二进制形式从高位到低位插入trie中,然后依次枚举每个数,在trie中贪心,即当前为0则向1走,为1则向0走。

一开始写动态分配节点的trie一直tle。。。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>
#include <vector>
using namespace std;
typedef long long ll;
const int N = 100005;

int n;
struct Edge {
    int v, w, nex;
    Edge() {}
    Edge(int v, int w, int nex) : v(v), w(w), nex(nex) {}
};
Edge e[N << 1];
int head[N], tot;
void add(int u, int v, int w) {
    e[tot] = Edge(v, w, head[u]);
    head[u] = tot++;
}
void read() {
    memset(head, -1, sizeof head);
    tot = 0;
    int u, v, w;
    for(int i = 1; i < n; ++i) {
        scanf("%d%d%d", &u, &v, &w);
        add(u, v, w);
        add(v, u, w);
    }
}
int d[N], vis[N];
void bfs() {
    queue<int> que;
    que.push(0);
    d[0] = 0;
    memset(vis, 0, sizeof vis);
    int u, v, w;
    vis[0] = 1;
    while(!que.empty()) {
        u = que.front(); que.pop();
        for(int i = head[u]; ~i; i = e[i].nex) {
            v = e[i].v; w = e[i].w;
            if(vis[v]) continue;
            d[v] = d[u] ^ w;
            vis[v] = 1;
            que.push(v);
        }
    }
}
int ch[N * 32][2];
struct Trie {
    int sz;
    Trie() { sz = 1; memset(ch[0], 0, sizeof ch[0]); }
    void _insert(int bs[]) {
        int u = 0;
        for(int i = 30; i >= 0; --i) {
            int c = bs[i];
            if(!ch[u][c]) {
                memset(ch[sz], 0, sizeof ch[sz]);
                ch[u][c] = sz++;
            }
            u = ch[u][c];
        }
    }
    int _search(int bs[]) {
        int u = 0, ans = 0;
        for(int i = 30; i >= 0; --i) {
            int c = bs[i];
            if(c == 1) {
                if(ch[u][0]) { ans += (1 << (i)); u = ch[u][0]; }
                else u = ch[u][1];
            }else {
                if(ch[u][1]) { ans += (1 << (i)); u = ch[u][1]; }
                else u = ch[u][0];
            }
        }
        return ans;
    }
};

int ans;
int b[35];
void get(int x) {
    int ls = 0;
    memset(b, 0, sizeof b);
    while(x) {
        b[ls++] = x % 2;
        x >>= 1;
    }
}
void solve() {
    Trie mytrie;
    ans = 0;
    for(int i = 0; i < n; ++i) {
        get(d[i]);
        mytrie._insert(b);
        ans = max(ans, mytrie._search(b));
    }
    printf("%d\n", ans);
}
int main() {
   // freopen("in.txt", "r", stdin);
    while(~scanf("%d", &n)) {
        read();
        bfs();
        solve();
    }
}

时间: 2024-12-24 15:36:15

Poj The xor-longest Path 经典题 Trie求n个数中任意两个异或最大值的相关文章

[经典面试题][百度]数组A中任意两个相邻元素大小相差1,在其中查找某个数。

题目 数组A中任意两个相邻元素大小相差1,现给定这样的数组A和目标整数t,找出t在数组A中的位置.如数组:[1,2,3,4,3,4,5,6,5],找到4在数组中的位置. 思路 这道题目最差时间复杂度也是O(N),所以重点在于能不能找到一种尽可能减少比较次数的方法. 如数组:[1,2,3,4,3,4,5,6,5],找到4在数组中的位置.4和1比较,差为3,那么即使最好情况(递增或者递减),4也就是在a[3]的位置,可以跳过a[1]a[2].这样在特定数组(目标值和a[1]相差很大)的情况下或许可以

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

The xor-longest Path Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 10038   Accepted: 2040 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. W

POJ 3764 The xor-longest Path ( 字典树应用—— 求连续段相异或最大最小的线性算法)(好题)

题意:已知:给出n个结点的树,定义:两结点间的权值为两点之间所有边相异或的值.求:树中的某两点间的最大权值. 思路:先说简单一点的题:有道CowXor,是一串线性序列,求某连续段异或的最大值,这题的思路是先求前i项序列相异或的值Si,所以x到y的连续异或就是Sx^Sy ,因为a^b = (a ^ c) ^ (b ^ c). 这题同样是这个思路把线性拓展到树上,先求任何点到某一定点的连续异或值,比如选根结点0,所以这时候有两种情况,1.x,y的路径通过了根结点,显然正确.2.x,y的路径不通过根结

51Nod - 1295:XOR key (可持久化Trie求区间最大异或)

给出一个长度为N的正整数数组A,再给出Q个查询,每个查询包括3个数,L, R, X (L <= R).求ALL 至 ARR 这R - L + 1个数中,与X 进行异或运算(Xor),得到的最大值是多少?Input第1行:2个数N, Q中间用空格分隔,分别表示数组的长度及查询的数量(1 <= N <= 50000, 1 <= Q <= 50000). 第2 - N+1行:每行1个数,对应数组A的元素(0 <= Aii <= 10^9). 第N+2 - N+Q+1行:

poj 1004:Financial Management(水题,求平均数)

Financial Management Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 126087   Accepted: 55836 Description Larry graduated this year and finally has a job. He's making a lot of money, but somehow never seems to have enough. Larry has deci

SGU 275 To xor or not to xor 高斯消元求N个数中选择任意数XORmax

275. To xor or not to xor The sequence of non-negative integers A1, A2, ..., AN is given. You are to find some subsequence Ai 1, Ai 2, ..., Ai k (1 <= i 1 < i 2 < ... < i k<= N) such, that Ai 1 XOR Ai 2 XOR ... XOR Ai k has a maximum value.

第14题:查找升序数组中的两数,使其和为输入数字

欢迎转载,转载请注明出处:http://blog.csdn.net/alading2009/article/details/45080773 第14题:输入一个已经按升序排序过的数组和一个数字,在数组中查找两个数,使得它们的和正好是输入的那个数字.要求: 时间复杂度是O(n).如果有多对数字的和等于输入的数字,输出任意一对即可.例如输入数组1.2.4.7.11.15和数字15.由于4+11=15,因此输出4和11. 两头向中间靠拢,因为是升序数组,两数之和大了就尾指针前移,两数之和小了就头指针后

[C++]LeetCode: 93 Binary Search Tree Iterator (经典题,非递归的中序遍历)

题目: Implement an iterator over a binary search tree (BST). Your iterator will be initialized with the root node of a BST. Calling next() will return the next smallest number in the BST. Note: next() and hasNext() should run in average O(1) time and u

经典题:求质数

#include<stdio.h>#include<math.h>int main(){    int n,i;    double t;    scanf("%d",&n); t=sqrt(n); for(i=2;i<=t;i++) {  if(n%i==0)  {     break;  } } if(i>t) {  printf("质数");  }  else {  printf("非质数");