zoukankan      html  css  js  c++  java
  • AcWing 144 最长异或值路径 (Trie)

    题目链接:https://www.acwing.com/problem/content/146/

    (D[i]) 表示 (i) 到根路径上的值的异或之和,
    则根据异或的性质,(u,v) 间路径的异或和即为 (D[u] ^ D[v])

    所以问题就变成了在 (D) 中选出异或值最大的两个数
    Trie树解决即可

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<iostream>
    #include<cmath>
    #include<stack>
    #include<queue>
    using namespace std;
    typedef long long ll;
    
    const int maxn = 3000010;
    
    int n, ans;
    int D[maxn];
    int root = 0, tot = 0;
    
    int h[maxn], cnt = 0;
    
    struct E{
    	int to, next, w;
    }e[100010 << 1];
    
    void add(int u, int v, int w){
    	e[++cnt].to = v;
    	e[cnt].w = w;
    	e[cnt].next = h[u];
    	h[u] = cnt;
    }
    
    struct Trie{
    	int son[2];
    }trie[maxn];
    
    void insert(int x){
    	int pos = root;
    	for(int i=31; i>=0; --i){
    		int num = ((x >> i) & 1);
    		if(!trie[pos].son[num]) trie[pos].son[num] = ++tot;
    		pos = trie[pos].son[num];
    	}
    }
    
    int query(int x){
    	int res = 0;
    	int pos = root;
    	for(int i=31; i>=0; --i){
    		int num = ((x >> i) & 1);
    		if(trie[pos].son[num ^ 1]){
    			pos = trie[pos].son[num ^ 1];
    			res ^= (1 << i);
    		}else{
    			pos = trie[pos].son[num];
    		}
    	} 
    	return res;
    }
    
    void dfs(int u, int par){
    	for(int i=h[u];i!=-1;i=e[i].next){
    		int v = e[i].to, w = e[i].w;
    		if(v == par) continue;
    		D[v] = D[u] ^ w;
    		dfs(v, u);
    	}
    }
    
    ll read(){ ll s=0,f=1; char ch=getchar(); while(ch<'0' || ch>'9'){ if(ch=='-') f=-1; ch=getchar(); } while(ch>='0' && ch<='9'){ s=s*10+ch-'0'; ch=getchar(); } return s*f; }
    
    int main(){
    	memset(h, -1, sizeof(h)); ans = 0;
    	n = read();
    	
    	int u, v, w;
    	for(int i=1;i<n;++i){
    		u = read(), v = read(), w = read();
    		++u, ++v;
    		add(u, v, w);
    		add(v, u, w);
    	}
    	
    	D[1] = 0;
    	dfs(1, 0);
    	
    	insert(D[1]);
    	for(int i=1;i<=n;++i){
    		ans = max(ans, query(D[i]));
    		insert(D[i]);
    	}
    	
    	printf("%d
    ", ans);
    	
    	return 0;
    }
    
  • 相关阅读:
    Ubuntu adb device
    ubuntu系统下创建软件桌面快捷方式
    Ubuntu 配置java环境变量
    Ubuntu 12.04 安装Chrome步骤
    java和php中static+final+synchronized 总结
    Sensor Hub 初探
    Ionic+PhoneGap+ Cordova
    Ionic初探 + 混合app的尝试
    ubuntu+dpkg+apt-get+aptitude 区别
    ubuntu下桌面系统及切换gdm+kdm+lightdm
  • 原文地址:https://www.cnblogs.com/tuchen/p/13944590.html
Copyright © 2011-2022 走看看