您的位置:首页 > 其它

[BZOJ1954]Pku3764 The xor-longest Path

2016-04-02 22:47 281 查看

Pku3764 The xor-longest Path

Description

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

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

1 2 3

2 3 4

2 4 6

Sample Output

7

HINT

The xor-longest path is 1->2->3, which has length 7 (=3 ⊕ 4)

注意:结点下标从1开始到N….

Solution

首先我们遇到的一个问题是快速得到任意两点之间路径的异或和的问题。

异或满足交换律和结合律,以0为不变元,这些性质与加法类似,联想加法,我们通常采取sum[u]+sum[v]-sum[lca(u,v)]-sum[lca(u,v)->fa]的方法,再联系异或自身的特殊性质(x^x=0),我们只需要f[u]^f[v]即可

然后我们发现我们需要做的是寻找f[u]^f[v]的最值

这是Trie树的经典问题

Code

#include <bits/stdc++.h>
using namespace std;

#define rep(i, l, r) for (int i = (l); i <= (r); i++)
#define per(i, r, l) for (int i = (r); i >= (l); i--)
#define debug(...) fprintf(stderr, __VA_ARGS__)
template<typename T> inline void read(T &x){
x = 0; T f = 1; char ch = getchar();
while (!isdigit(ch)) { if (ch == '-') f = -1; ch = getchar(); }
while (isdigit(ch))  { x = x * 10 + ch - '0'; ch = getchar(); }
x *= f;
}

const int INF = 0x7fffffff;
const int N = 1e5+100;
const int LEN = 35;
int bin[LEN], n, f
;
struct Node{ int v, c; Node *nxt; }pool[N<<1], *tail=pool, *g
;
struct Trie{ Trie *c[2]; }POOL[N*LEN], *TAIL=POOL, *root;
inline void ckmax(int &x, int y){ if (x < y) x = y; }
inline void addedge(int u, int v, int c){
tail->v = v; tail->c = c; tail->nxt = g[u]; g[u] = tail++;
tail->v = u; tail->c = c; tail->nxt = g[v]; g[v] = tail++;
}
void dfs(int x, int fa){
for (Node *p = g[x]; p; p=p->nxt)
if (p->v != fa) { f[p->v] = f[x] ^ p->c; dfs(p->v, x); }
}
void insert(int x, int p, Trie *&rt){
if (!rt) rt = TAIL++;
if (p<0) return;
insert(x, p-1, rt->c[(x&bin[p])>>p]);
}
int query(int x, int p, Trie *rt){
if (p<0) return 0;
int d = (x&bin[p])>>p;
return rt->c[!d] ? bin[p]+query(x, p-1, rt->c[!d]) : query(x, p-1, rt->c[d]);
}
int main(){
bin[0] = 1; rep(i, 1, 30) bin[i] = bin[i-1] << 1;

read(n);
rep(i, 1, n-1){ int u, v, c;
read(u); read(v); read(c);
addedge(u, v, c);
}
dfs(1, 0);
rep(i, 1, n) insert(f[i], 30, root);

int ans = -INF;
rep(i, 1, n) ckmax(ans, query(f[i], 30, root));
printf("%d\n", ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: