zoukankan      html  css  js  c++  java
  • bzoj 1954 & poj 3764 The xor-longest Path dfs+Trie

    题目大意

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

    题解

    因为(xor)操作满足可结合性,所以有
    (a ext{ }xor ext{ }b ext{ }xor ext{ }b = a)
    那么我们可以计算出每个点到根的xor距离,设为(dis)
    那么我们知道(dis_u ext{ }xor ext{ }dis_v)(u,v)之间的距离的xor值
    所以我们把所有的(dis)插到01Trie里,再对每个(dis)值求最大即可

    Code

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    typedef long long ll;
    inline void read(int &x){
    	x=0;char ch;bool flag = false;
    	while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true;
    	while(x=10*x+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x;
    }
    inline int cat_max(const int &a,const int &b){return a>b ? a:b;}
    inline int cat_min(const int &a,const int &b){return a<b ? a:b;}
    const int maxn = 100010;
    struct Edge{
    	int to,next,dis;
    }G[maxn<<1];
    int head[maxn],cnt;
    void add(int u,int v,int d){
    	G[++cnt].to = v;
    	G[cnt].next = head[u];
    	head[u] = cnt;
    	G[cnt].dis = d;
    }
    inline void insert(int u,int v,int d){
    	add(u,v,d);add(v,u,d);
    }
    int dis[maxn];
    #define v G[i].to
    void dfs(int u,int fa){
    	for(int i = head[u];i;i=G[i].next){
    		if(v == fa) continue;
    		dis[v] = dis[u]^G[i].dis;
    		dfs(v,u);
    	}
    }
    #undef v
    int ch[maxn*32][2],nodecnt;
    bool ed[maxn*32];
    inline void insert(int x){
    	int nw = 0;
    	for(int i = 31;i;--i){
    		int id = (bool)(x & (1 << (i-1)));
    		if(ch[nw][id] == 0) ch[nw][id] = ++nodecnt;
    		nw = ch[nw][id];
    	}ed[nw] = true;
    }
    inline int query(int x){
    	int ret = 0,nw = 0;
    	for(int i=31;i;--i){
    		int id = (bool)(x & (1 << (i-1)));
    		if(ch[nw][id^1] != 0){
    			ret |= (1<<(i-1));
    			nw = ch[nw][id^1];
    		}else nw = ch[nw][id];
    	}return ret;
    }
    inline void init(){
    	memset(head,0,sizeof head);
    	memset(ch,0,sizeof ch);
    	memset(ed,0,sizeof ed);
    	memset(dis,0,sizeof dis);
    	cnt = nodecnt = 0;
    }
    int main(){
    	int n;
    	while(scanf("%d",&n) != EOF){
    		init();
    		int u,v,d;
    		for(int i=1;i<n;++i){
    			read(u);read(v);read(d);
    			insert(u,v,d);
    		}dfs(1,0);
    		for(int i=1;i<=n;++i) insert(dis[i]);
    		int ans = 0;
    		for(int i=1;i<=n;++i){
    			ans = max(ans,query(dis[i]));
    		}printf("%d
    ",ans);		
    	}
    	getchar();getchar();
    	return 0;
    }
    
  • 相关阅读:
    理解和驾驭软件开发的那些事儿
    Dubbo 泛化调用的参数解析问题及一个强大的参数解析工具 PojoUtils
    HBase指定大量列集合的场景下并发拉取数据时卡住的问题排查
    阅读的收获
    碎碎念集萃二十
    《深度工作》学习笔记
    系统思考学习笔记
    思考力笔记
    碎碎念集萃十九
    设计方案考量的准则与细则
  • 原文地址:https://www.cnblogs.com/Skyminer/p/6417332.html
Copyright © 2011-2022 走看看