The xor-longest Path
Time Limit: 2000MS Memory Limit: 65536K
Total Submissions: 5242 Accepted: 1140
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)=\oplus{e \in p}w(e)
⊕ 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)
题意:在一棵树中找最大的XOR道路;
思路:1.异或性质:a^b=(a^c)^(b^c)—>dfs取任意根做异或;
2.n^2的两次FOR—>字典序时间换空间找特定序列,枚举+贪心以0,1,做关键字在字典树上找当前最优解;
3.*小优化:FOR时find后insert,保证最优解仍存在;
#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<string.h>
#define clr(p) memset(p,0,sizeof(p))
#define MAXN 110500
using namespace std;
int head[MAXN],next[MAXN*2],to[MAXN*2],val[MAXN*2];
int XOR[MAXN];
int tot;
int sum;
int n;
struct node{
int ch[2];
void init() {
ch[0]=ch[1]=0;
}
}t[31*MAXN];
void add(int aa,int bb,int cc)
{
to[++tot]=bb;
val[tot]=cc;
next[tot]=head[aa];
head[aa]=tot;
}
void dfs(int x,int now,int pre)
{
XOR[x]=now;
for(int i=head[x];i!=-1;i=next[i])
{
int v=to[i];
if(v==pre) continue;
dfs(v,now^val[i],x);
}
}
void insert(int x)
{
int ret=0,now=0;
for(int j=30;j>=0;j--)
{
if((1<<j)&x) ret=1;
else ret=0;
if(!t[now].ch[ret]) t[now].ch[ret]=++sum;
t[sum].init();
now=t[now].ch[ret];
}
}
int solve(int x)
{
int ret=0;
int now=0;
for(int i=30;i>=0;i--)
{
int p=(1<<i)&x;
if(p) p=0;
else p=1;
if(t[now].ch[p]) ret+=(1<<i);
else p^=1;
now=t[now].ch[p];
}
//maintain,to find the curent best sol. for whats after x;
return ret;
}
int main()
{
while( (scanf("%d",&n))!=EOF )
{
sum=tot=0;
memset(head,-1,sizeof(head));
clr(to),clr(next),clr(val),clr(XOR);
t[0].init();
int aa,bb,cc;
for(int i=1;i<n;i++)
{
scanf("%d%d%d",&aa,&bb,&cc);
aa++;
bb++;
add(aa,bb,cc);
add(bb,aa,cc);
}
dfs(1,0,-1);
int ans=0;
for(int i=1;i<=n;i++)
insert(XOR[i]);
for(int i=1;i<=n;i++) ans=max(ans,solve(XOR[i]));
printf("%d\n",ans);
}
}
类似题:codeforces 282E - Sausage Maximization
#include<iostream>
#include<string.h>
#include<algorithm>
#include<stdio.h>
#define LL long long
using namespace std;
int n;
LL pre[100005],suf[100005],a[100005];
struct node{
int ch[2];
}t[100005*50];
LL ans;
int tot=0;
inline void add(LL x)
{
int now=0;
for(int i=50;i>=0;i--)
{
LL tmp=(1LL<<i)&x;
if(tmp) tmp=1;
if(!t[now].ch[tmp]) t[now].ch[tmp]=++tot;
now=t[now].ch[tmp];
}
}
inline LL solve(LL x)
{
LL ret=0;
int now=0;
for(int i=50;i>=0;i--)
{
LL tmp=(1LL<<i)&x;
if(tmp) tmp=0;
else tmp=1;
if(t[now].ch[tmp]) ret+=(1LL<<i);
else tmp^=1;
now=t[now].ch[tmp];
}
return ret;
}
int main()
{
scanf("%d",&n);
ans=0;
for(int i=1;i<=n;i++)
{
scanf("%I64d",&a[i]);
pre[i]=pre[i-1]^a[i];
}
for(int i=n;i>=1;i--)
suf[i]=suf[i+1]^a[i];
for(int i=1;i<=n+1;i++)
{
add(pre[i-1]);
ans=max(ans,solve(suf[i]));
}
printf("%I64d",ans);
}