首页 > 其他分享 >题解:P4551 最长异或路径

题解:P4551 最长异或路径

时间:2025-01-23 15:23:27浏览次数:1  
标签:int 题解 P4551 son trie 异或 num 节点

分析

首先我们有如下结论:

设两个节点到根节点的路径异或值为 \(x_1,x_2\),则这两个节点之间的路径异或值为 \(x_1 \operatorname{xor} x_2\)。

因此可以先求出每个节点到根节点的路径异或值,那么问题就转化成了:从 \(n\) 个整数中选两个进行异或运算,得到的结果最大是多少。

考虑使用字典树。可以将每个节点到根节点的路径异或值的二进制形式放进字典树里,答案即为字典树中与每个异或值取反后的结果匹配程度最高的值中的最大值。

细节内容见代码注释。

Code

#include<bits/stdc++.h>
#define i64 long long
#define max(x,y) ((x)>(y)?(x):(y))

using namespace std;

constexpr int N=1e5+5;
int n;

namespace Trie{
	int tot_trie;
	struct Node_trie{int son[2];}trie[int(3.1e6+5)];
	void insert_trie(int x){
		int p=0;
		for(int i=30;i>=0;--i){
			int num=x>>i&1;//二进制下从右往左数第 i+1 位的值 
			if(trie[p].son[num]==0)trie[p].son[num]=++tot_trie;
			p=trie[p].son[num];
		}
	}
	int query_trie(int x1){
		//按位取反(~ 运算符会把符号位也取反) 
		int x2=x1;
		for(int i=0;i<=30;++i)x2^=(1<<i);
		
		int p=0,res=0;
		for(int i=30;i>=0;--i){
			int num=x2>>i&1;
			//没有匹配的,只能走另一条路 
			if(trie[p].son[num]==0)
				p=trie[p].son[num^1];
			//匹配上了 
			else
				p=trie[p].son[num],
				res+=(1<<i);
		}
		return res;
	}
}

using namespace Trie;

namespace Graph{
	int tot_edge,hd[N];
	struct Edge{int to,val,lst;}g[N*2];
	void add_edge(int u,int v,int w){
		g[++tot_edge]=Edge{v,w,hd[u]};
		hd[u]=tot_edge;
	}
	
	//求每个节点到根节点的路径异或值 
	int xor_sum[N];
	void dfs(int x,int fa){
		//放进字典树里 
		insert_trie(xor_sum[x]);
		
		for(int i=hd[x];~i;i=g[i].lst)
			if(g[i].to!=fa){
				xor_sum[g[i].to]=xor_sum[x]^g[i].val;
				dfs(g[i].to,x);
			}
		return;
	}
}

using namespace Graph;

int main(){
	ios::sync_with_stdio(false),
	cin.tie(nullptr),cout.tie(nullptr);
	
	memset(hd,-1,sizeof hd);
	
	cin>>n;
	for(int i=1;i<n;++i){
		int x1,x2,x3;
		cin>>x1>>x2>>x3;
		
		add_edge(x1,x2,x3),add_edge(x2,x1,x3);
	}
	
	dfs(1,0);
	
	int ans=0;
	for(int i=1;i<=n;++i)
		ans=max(ans,query_trie(xor_sum[i]));
	
	cout<<ans<<endl;
	return 0;
}

标签:int,题解,P4551,son,trie,异或,num,节点
From: https://www.cnblogs.com/ezhe/p/18687813

相关文章

  • [BZOJ4671] 异或图 题解
    我能说什么!抽象了这!看到\(n\le10\)的黑题顿感大事不妙。我们考虑设\(f(i)\)表示将\(n\)个点划分为至少\(i\)个连通块时的方案数。我们可以暴力枚举每个点在哪个连通块里。划分方案是\(Bell(n)\le21147\)的。显然的,相同块内暂时忽略,不同块间不能有边。于是我们将每......
  • [BZOJ3622] 已经没有什么好害怕的了 题解
    发现难以维护差值,于是令\(K=\frac{n+k}2\),这样就把问题转化为了“糖果”比“药片”大的组数为\(K\)的情况有多少种。设\(dp_{i,j}\)表示我们用前\(i\)个“糖果”和“药片”配对,至少有\(j\)组“糖果”比“药片”大,有多少种情况;\(c_i\)表示有多少个“药片”比第\(i\)个......
  • [BZOJ3622] 已经没有什么好害怕的了 题解
    发现难以维护差值,于是令\(K=\frac{n+k}2\),这样就把问题转化为了“糖果”比“药片”大的组数为\(K\)的情况有多少种。设\(dp_{i,j}\)表示我们用前\(i\)个“糖果”和“药片”配对,至少有\(j\)组“糖果”比“药片”大,有多少种情况;\(c_i\)表示有多少个“药片”比第\(i\)个......
  • [BZOJ4665] 小w的喜糖 题解
    我们先假设同种糖间存在差异。设\(f_{i,j}\)表示前\(i\)种糖至少有\(j\)人拿到的糖和原来一样,\(c_i\)表示拿第\(i\)种糖的人的个数,则有:\[f_{i,j}=\sum_{k=0}^{\min(j,c_i)}f_{i-1,j-k}\binom{c_i}kc_i^\underlinek\]设\(g_i\)表示所有人中恰好有\(i\)人拿到的糖......
  • [FJOI2016] 建筑师 题解
    显然有一个\(dp\)思路。设\(f_{i,j}\)表示现在修了\(i\)栋楼,从第一栋楼外侧能看到\(j\)栋楼的方案数,显然有:\[f_{i,j}=\begin{cases}[i=0](j=0)\\f_{i-1,j-1}+(i-1)f_{i-1,j}(j\ne0)\end{cases}\]一眼\(f_{i,j}=\begin{bmatrix}i\\j\end{bmatrix}\)。那么答案即为:\[\s......
  • [BZOJ5093] 图的价值 题解
    考虑计算一个点的贡献,最后\(\timesn\)即为所求。显然一个点的贡献为\(\sum\limits_{i=0}^{n-1}\binom{n-1}ii^k2^{\frac{(n-1)(n-2)}2}\),则有:\[\sum_{i=0}^{n-1}\binom{n-1}ii^k2^{\frac{(n-1)(n-2)}2}=2^{\frac{(n-1)(n-2)}2}\sum_{i=0}^{n-1}\sum_{j=0}^k\begin{Bmatrix}k......
  • [TJOI/HEOI2016] 求和 题解
    为什么又是佳媛姐姐啊啊啊!斯特林数在这道题中不好处理,直接拆开:\[f(n)=\sum_{i=0}^n\sum_{j=0}^i\begin{Bmatrix}i\\j\end{Bmatrix}2^jj!\]\[=\sum_{j=0}^n2^jj!\sum_{i=0}^n\sum_{k=0}^j\frac{(-1)^k(j-k)^i}{k!(j-k)!}\]\[=\sum_{j=0}^n2^jj!\sum_{k=0}^j\frac{(-1)^k\sum\l......
  • [联合省选 2020A] 组合数问题 题解
    后面有一只大大的组合数,考虑下降幂干过去。\(x^k\)并不好使,这边考虑转化\(f(x)=\suma_ix^i=\sumb_ix^\underlinei\)。\[\sum_{k=0}^nf(k)x^k\binomnk=\sum_{k=0}^nx^k\sum_{i=0}^mb_ik^\underlinei\binomnk\]\[=\sum_{k=0}^nx^k\sum_{i=0}^mb_in^\underlinei\binom{n-i......
  • Bear and Bad Powers of 42 题解
    题目描述定义一个正整数是坏的,当且仅当它是\(42\)的幂次,否则它是好的。给定长为\(n\)的序列\(a_i\),保证初始所有数都是好的。接下来\(q\)次操作:1i:查询\(a_i\)。2lrx:将\(a_l,\cdots,a_r\)赋值为一个好的数\(x\)。3lrx:将\(a_l,\cdots,a_r\)加上\(......
  • [ARC178C] Sum of Abs 2 题解
    首先想到能不能用差分搞搞,但是给自己绕进去了/kel我们不妨给\(\{b_L\}\)定个不降的序(如果打在数轴上,显然序和答案无关),于是可以拿掉绝对值。注意到这个和式(记其结果为\(x\))中每个\(b_i\)的贡献系数\(c_i=2i-L-1\),于是有:\[x=\sum_{i=1}^{L}b_ic_i\]直接做不......