zoukankan      html  css  js  c++  java
  • [BZOJ1954][Pku3764]The xor-longest Path

    [BZOJ1954][Pku3764]The xor-longest Path

    试题描述

     给定一棵n个点的带权树,求树上最长的异或和路径

    输入

    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.

    输出

    For each test case output the xor-length of the xor-longest path.

    输入示例

    4
    1 2 3
    2 3 4
    2 4 6

    输出示例

    7

    数据规模及约定

    见“输入

    题解

    这题中英文切换的。。。

    一开始理解错题意了。。。把边权看成了点权,搞得还以为要点分治 + trie 树。。。

    如果是边权,那么不难发现 xor(u, v)(即 u 到 v 的亦或和)= d[u] ^ d[v],d[u] 表示 u 到根节点的亦或和。

    于是搞出 d 数组,把每个数插到 trie 中,然后对每个 d[i] 查询一遍 trie 树中与 d[i] 亦或的最大值,方法是贪心,从高位到底位尽量往与当前二进制位不同的方向走。

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cctype>
    #include <algorithm>
    #include <vector>
    using namespace std;
    
    int read() {
    	int x = 0, f = 1; char c = getchar();
    	while(!isdigit(c)){ if(c == '-') f = -1; c = getchar(); }
    	while(isdigit(c)){ x = x * 10 + c - '0'; c = getchar(); }
    	return x * f;
    }
    
    #define maxn 100010
    #define maxm 200010
    #define maxnode 3200010
    
    int n, m, head[maxn], nxt[maxm], to[maxm], dist[maxm], val[maxn];
    
    void AddEdge(int a, int b, int c) {
    	to[++m] = b; dist[m] = c; nxt[m] = head[a]; head[a] = m;
    	swap(a, b);
    	to[++m] = b; dist[m] = c; nxt[m] = head[a]; head[a] = m;
    	return ;
    }
    
    int rt, ToT, ch[maxnode][2];
    bool num[32];
    void insert(int x) {
    	int cnt = 0; memset(num, 0, sizeof(num));
    	while(x) num[++cnt] = x & 1, x >>= 1;
    	cnt = 31;
    	int u = rt;
    	for(int i = cnt; i; i--) {
    		if(!ch[u][num[i]]) ch[u][num[i]] = ++ToT;
    		u = ch[u][num[i]];
    	}
    	return ;
    }
    void build(int u, int fa, int v) {
    	insert(v); val[u] = v;
    	for(int e = head[u]; e; e = nxt[e]) if(to[e] != fa)
    		build(to[e], u, v ^ dist[e]);
    	return ;
    }
    int query(int x) {
    	int cnt = 0; memset(num, 0, sizeof(num));
    	while(x) num[++cnt] = x & 1, x >>= 1;
    	cnt = 31;
    	int u = rt, ans = 0;
    	for(int i = cnt; i; i--)
    		if(ch[u][num[i]^1]) ans = ans << 1 | 1, u = ch[u][num[i]^1];
    		else ans <<= 1, u = ch[u][num[i]];
    	return ans;
    }
    
    int main() {
    	n = read();
    	for(int i = 1; i < n; i++) {
    		int a = read(), b = read(), c = read();
    		AddEdge(a, b, c);
    	}
    	
    	ToT = rt = 1;
    	build(1, 0, 0);
    	int ans = 0;
    	for(int i = 1; i <= n; i++) ans = max(ans, query(val[i]));
    	
    	printf("%d
    ", ans);
    	
    	return 0;
    }
    
  • 相关阅读:
    HDU 1097 a hard puzzle
    HDU 4588 Count The Carries
    不想用锐捷怎么办?锐捷出问题|锐捷不能用怎么办?用menohust代替吧
    线段树及其变种的相关资料(不定期更新)
    UVa 10075
    UVa 1301
    UVa 10256
    UVa 1453
    计算几何相关资料+题目推荐(不定期补充)
    UVa 11524
  • 原文地址:https://www.cnblogs.com/xiao-ju-ruo-xjr/p/6484998.html
Copyright © 2011-2022 走看看