The xor-longest Path
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 Sample Output Hint The xor-longest path is 0->1->2, which has length 7 (=3 ⊕ 4) Source |
算法分析:
题意:
给出一棵带权树,请找出树上的一条路径,使其边上权值的异或和最大。
分析:
首先我们考虑从根向下dfs,记录下每个点i到根上权值的异或和val[i]。根据异或和的性质:x Xor y Xor y=x。所以我们可以由val数组组合得出树上任意两点之间路径的异或和。
然后就简单了:CH 1602 The XOR Largest Pair 字典树+异或
这题很坑,注意long long 和数据范围
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <stack>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
const int N=200010;
#define ll long long
struct node
{
int v;///终端点
int next;///下一条同样起点的边号
ll w;///权值
}edge[N<<1];///无向边,2倍
int head[N];///head[u]=i表示以u为起点的所有边中的第一条边是 i号边
int tot; ///总边数
int vis[N];
ll val[N]; ///val[i]表示从根节点到i的路径的所有边权的异或值
void add(int u,int v,int w)
{
edge[tot].v=v;
edge[tot].w=w;
edge[tot].next=head[u];
head[u]=tot++;
}
int n,m;
int dfs(int u,ll w)
{
vis[u]=1;
//cout<<u<<endl;
for(int i=head[u];i!=-1;i=edge[i].next)
{
int v= edge[i].v;
if(!vis[v])
dfs(v,w^edge[i].w);
}
val[u]=w;
}
const int maxnode=200000+100;
const int sigma_size=3;
struct Trie
{
int ch[maxnode<<4][sigma_size];//注意要多开10倍
int sz;
void clear()
{
sz=1;
memset(ch[0],0,sizeof(ch[0]));
}
void insert(ll x)
{
int u=0;
for(int i=31;i>=0;i--)
{
int id=(x>>i)&1;//取出第i位
if(ch[u][id]==0)
{
ch[u][id]=sz;
memset(ch[sz],0,sizeof(ch[sz]));
sz++;
}
u=ch[u][id];
}
}
ll find(ll x)
{
ll ans=0,u=0;
for(int i=31;i>=0;i--)
{
int id=(x>>i)&1;
int y=id^1; //找与id不同的
if(ch[u][y]==0)
{
u=ch[u][id];
ans<<=1; //相同为0,ans=ans*2
}
else
{
u=ch[u][y];
ans=ans<<1|1; //不同为1,ans=ans*2+1
}
}
return ans;
}
};
Trie trie;
int main()
{
while(scanf("%d",&n)!=EOF)
{
memset(head,-1,sizeof(head));
memset(val,0,sizeof(val));
memset(vis,0,sizeof(vis));
trie.clear();
for (int u,v,i=1;i<n;i++)
{
ll w;
scanf("%d%d%lld",&u,&v,&w);
u++;v++;
add(u,v,w);
add(v,u,w);
}
dfs(1,0);
ll maxx=0;
for(int i=1;i<=n;i++)
{
maxx=max(maxx,trie.find(val[i]));
trie.insert(val[i]);
}
cout<<maxx<<endl;
}
return 0;
}