• 洛谷 P4551 最长异或路径


    题目描述

    给定一棵 nn 个点的带权树,结点下标从 11 开始到 NN 。寻找树中找两个结点,求最长的异或路径。

    异或路径指的是指两个结点之间唯一路径上的所有节点权值的异或。

    输入输出格式

    输入格式:

    第一行一个整数 NN ,表示点数。

    接下来 n-1n1 行,给出 u,v,wu,v,w ,分别表示树上的 uu 点和 vv 点有连边,边的权值是 ww 。

    输出格式:

    一行,一个整数表示答案。

    输入输出样例

    输入样例#1: 
    4
    1 2 3
    2 3 4
    2 4 6
    输出样例#1: 
    7

    说明

    最长异或序列是1-2-3,答案是 7 (=3 ⊕ 4)

    数据范围

    1le n le 100000;0 < u,v le n;0 le w < 2^{31}1n100000;0<u,vn;0w<2^31

        为什么不叫trie树模板题呢???

        练练板子hhhh

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int maxn=100005;
    int ci[35],n,m,Xor[maxn],c=0,ch[maxn*57][2],R=0,A=0;
    int to[maxn*2],ne[maxn*2],val[maxn*2],num,hd[maxn];
    inline void add(int x,int y,int z){ to[++num]=y,ne[num]=hd[x],hd[x]=num,val[num]=z;}
    
    inline void Ins(int x){
    	int now=R;
    	for(int i=30,u;i>=0;i--){
    		u=(ci[i]&x)?1:0;
    		if(!ch[now][u]) ch[now][u]=++c;
    		now=ch[now][u];
    	}
    }
    
    int F(int x){
    	int now=R,an=0;
    	for(int i=30,u;i>=0;i--){
    		u=(ci[i]&x)?0:1;
    		if(ch[now][u]) an+=ci[i],now=ch[now][u];
    		else now=ch[now][u^1];
    	}
    	return an;
    }
    
    void dfs(int x,int fa){
    	A=max(A,F(Xor[x])),Ins(Xor[x]);
    	for(int i=hd[x];i;i=ne[i]) if(to[i]!=fa){
    		Xor[to[i]]=Xor[x]^val[i];
    		dfs(to[i],x);
    	}
    }
    
    int main(){
    	ci[0]=1;
    	for(int i=1;i<=30;i++) ci[i]=ci[i-1]<<1;
    	scanf("%d",&n);
    	int uu,vv,ww;
    	for(int i=1;i<n;i++) scanf("%d%d%d",&uu,&vv,&ww),add(uu,vv,ww),add(vv,uu,ww);
    	dfs(1,-1);
    	printf("%d
    ",A);
    	return 0;
    }
    

      

  • 相关阅读:
    ubuntu18.04下eclipse修改maven源为阿里源
    Java中使用队列Queue
    Redis学习笔记——Redis的基本操作
    ubuntu安装redis
    Spring Boot使用监听器Listener
    Spring Boot中在程序中获得application.properties中的值
    Spring Boot使用过滤器Filter
    基于GTID的主从架构异常处理流程
    goroutine与调度器
    使用synergyc共享键鼠
  • 原文地址:https://www.cnblogs.com/JYYHH/p/9026855.html
Copyright © 2020-2023  润新知