您的位置:首页 > 其它

POJ 3764 The xor-longest Path 字典树 异或性质

2014-11-16 23:27 337 查看
题意:给出一棵树,每条边上都有权值。求在树上的一条路径,使在这条路径上的异或和最大。

思路:对于异或,我们要考虑其二进制分解。

因为异或满足结合性,所以xorsum[u,v] = xorsum[0,u] ^ xorsum[0,v];我们将任意一点作为根,这样xorsum[0.v]就能dfs求出。

同样,由于上面的公式,对于任意一点u的到其他路径的异或和的最大值,其实就是相当于查询其他的所有的xorsum[0,v]和xorsum[0,v]的最大值。这个转化成了在N个数中查找和给定数异或和最大的值。这个可以用字典树来加速查询,复杂度为O(32)。

复杂度:O(32N).

代码如下:

#include <cstdio>
#include <algorithm>
#include <cstring>

using namespace std;

const int MAX = 100010;

struct edge{
int to,w;
edge(){}
edge(int t, int ww):w(ww),to(t){}
} edges[MAX<<1];

int head[MAX],nxt[MAX<<1],tot,N,xo[MAX];
char str[40];

void init()
{
tot = 0;
memset(head,-1,sizeof(head));
}

void addedge(int u, int v, int w)
{
edges[tot] = edge(v,w);
nxt[tot] = head[u], head[u] = tot++;
edges[tot] = edge(u,w);
nxt[tot] = head[v], head[v] = tot++;
}

void dfs(int u, int fa)
{
for(int i = head[u]; ~i; i = nxt[i]){
edge & e = edges[i];
if(e.to == fa) continue;
xo[e.to] = xo[u] ^ e.w;
dfs(e.to,u);
}
}
void tostr(int n)
{
for(int i = 31; i >= 0; --i)
str[i] = n % 2 + '0', n >>= 1;
str[32] = 0;
}

int tonum()
{
int t = 1,ans = 0;
for(int i = 31; i >= 0; --i)
ans += (str[i] - '0') * t, t *= 2;
return ans;
}

struct Trie{
static const int CHARSET = 2;
static const int BASE  = '0';
static const int MAXNODE = 4000000;

int child[MAXNODE][CHARSET];
int v[MAXNODE];
int root,sz;
int id;

Trie(){init();}

void init(){
root = 1,sz = 1,id = 1;
memset(child[1],0,sizeof(child[1]));
memset(v,0,sizeof(v));
}
void insert(char * s){
int * cur = & root;
for(char *p = s; *p; ++p){
cur = &child[*cur][*p - BASE];
if(*cur == 0){
*cur = ++sz;
memset(child[*cur],0,sizeof(child[*cur]));
}
}
}
int query(int num){
tostr(num);
int * cur = & root;
for(char * p = str; *p ; ++p){
int c = (*p - BASE) ^ 1;
if(child[*cur][c] != 0){
*p += c;
cur = &child[*cur][c];
}
else{
cur = &child[*cur][c^1];
*p = '0';
}
}
return tonum();
}
} trie;

int main(void)
{
int u,v,w;
//freopen("input.txt","r",stdin);
while(~scanf("%d",&N)){
init();
for(int i = 0; i < N - 1; ++i){
scanf("%d%d%d",&u,&v,&w);
addedge(u,v,w);
}
xo[0] = 0;
dfs(0,-1);
trie.init();
for(int i = 0; i < N; ++i){
tostr(xo[i]);
trie.insert(str);
}
int ans = 0;
for(int i = 0; i < N; ++i)
ans = max(ans,trie.query(xo[i]));
printf("%d\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: