首页 > 其他 > 详细

Poj3764 The XOR-longest Path

时间:2018-11-01 18:54:40      阅读:137      评论:0      收藏:0      [点我收藏+]

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


同学考我的一道题

很巧妙,首先我们来兴暴力维护是n^3的,然后从异或的性质来考虑

异或的值是满足前缀和性质的,所以我们只需要枚举两个节点,然后现在的会见复杂度是n^2

然后来兴我们在维护完前缀和之后,只需要选择两个异或之后结果最大的两个前缀和

就正好可以用Trie来维护,时间复杂度就变成了n*31(因为数据在int范围内)

下面给出代码:

#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#define register int int
using namespace std;
inline int rd(){
    int x=0,f=1;
    char ch=getchar();
    for(;!isdigit(ch);ch=getchar()) if(ch==-) f=-1;
    for(;isdigit(ch);ch=getchar()) x=x*10+ch-0;
    return x*f;
}
inline int max(int x,int y){return x>y?x:y;}
inline void write(int x){
    if(x<0) putchar(-),x=-x;
    if(x>9) write(x/10);
    putchar(x%10+0);
    return ;
}
int n;
int cnt[200006];
int head[200006];
int nxt[200006],to[200006],dis[200006];
int total=0;
inline void add(int x,int y,int z){
    total++;
    to[total]=y;
    dis[total]=z;
    nxt[total]=head[x];
    head[x]=total;
    return ;
}
int sum[200006];
inline void dfs(int x,int fa){
    for(int e=head[x];e;e=nxt[e]){
        if(to[e]!=fa&&!sum[to[e]]){
            sum[to[e]]=sum[x]^dis[e];
            dfs(to[e],x);
        }
    }
    return ;
}
int a[32];
int trie[3200006][2];
int tot=1;
inline void build(int len){
    int c=1;
    for(int i=32;i>=1;i--){
        if(!trie[c][a[i]]) trie[c][a[i]]=++tot;
        c=trie[c][a[i]];
    }
    return ;
}
int p[100006];
inline int solve(int len){
    int c=1,num=0;
    for(int i=32;i>=1;i--){
        if(trie[c][!a[i]]){
            c=trie[c][!a[i]];
            num+=p[i-1];
        }
        else c=trie[c][a[i]];
    }
    return num;
}
int main(){
    p[0]=1;
    for(int i=1;i<=31;i++) p[i]=p[i-1]*2;
    n=rd();
    for(int i=1;i<n;i++){
        int x=rd(),y=rd(),z=rd();
        add(x,y,z);
    }
    dfs(1,-1);
    for(int i=1;i<=n;i++){
        memset(a,0,sizeof(a));
        int h=sum[i];
        int pos=0;
        while(h){
            a[++pos]=h%2;
            h>>=1;
        }
        build(pos);
    }
    int ans=0;
    for(int i=1;i<=n;i++){
        memset(a,0,sizeof(a));
        int h=sum[i];
        int pos=0;
        while(h){
            a[++pos]=h%2;
            h>>=1;
        }
        ans=max(ans,solve(pos));
    }
    write(ans);
    return 0;
}

 

Poj3764 The XOR-longest Path

原文:https://www.cnblogs.com/WWHHTT/p/9891006.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!