当前位置: 首页 > article >正文

【洛谷】P4551 最长异或路径 的题解

【洛谷】P4551 最长异或路径 的题解

洛谷传送门

题解

神奇的字典树咩呀qaq

看到异或,我们首先很容易想到 trie 树 还有 线性基。但是这题明显是字典树。

指定一个根 r o o t root root,用 t r i e [ u ] [ v ] trie[u][v] trie[u][v] 表示 u u u v v v 之间的路径的边权异或和,那么 t r i e [ u ] [ v ] = t r i e [ r o o t ] [ u ] ⊕ t r i e [ r o o t ] [ v ] trie[u][v]=trie[root][u]\oplus trie[root][v] trie[u][v]=trie[root][u]trie[root][v],因为 LCA 以上的部分异或两次抵消了。

那么,如果将所有 t r i e [ r o o t ] [ u ] trie[root][u] trie[root][u] 插入到一棵 trie 中,就可以对每个 t r i e [ r o o t ] [ u ] trie[root][u] trie[root][u] 快速求出和它异或和最大的 t r i e [ r o o t ] [ v ] trie[root][v] trie[root][v]

从 trie 的根开始,如果能向和 T ( r o o t , u ) T(root, u) T(root,u) 的当前位不同的子树走,就向那边走,否则没有选择。

对于每一位进行贪心,如果这一位有一个与它不同的,即异或后是 1 1 1,那我们就顺着这条路往下走;否则就顺着原路往下走。

贪心的正确性:如果这么走,这一位为 1 1 1;如果不这么走,这一位就会为 0 0 0。而高位是需要优先尽量大的。由于高位大决定一切,所以我们贪心是对的。

代码

#include <bits/stdc++.h>
#define re register
#define lowbit(x) x & (-x)
#define endl "\n"
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
namespace fastIO {
	inline int read() {
		register int x = 0, f = 1;
		register char c = getchar();
		while (c < '0' || c > '9') {
			if(c == '-') f = -1;
			c = getchar();
		}
		while (c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
		return x * f;
	}
	inline void write(int x) {
		if(x < 0) putchar('-'), x = -x;
		if(x > 9) write(x / 10);
		putchar(x % 10 + '0');
		return;
	}
}
using namespace fastIO;
int head[100005], nxt[100005 << 1], to[100005 << 1], weight[100005 << 1], cnt;
int n, dis[100005], ch[100005 << 5][2], tot = 1, ans;
void insert(int x) {
	for(int i = 30, u = 1; i >= 0; i --) {
		int c = ((x >> i) & 1);
		if(!ch[u][c]) ch[u][c] = ++ tot;
		u = ch[u][c];
	}
}
void get(int x) {
	int res = 0;
	for(int i = 30, u = 1; i >= 0; i --) {
		int c = ((x >> i) & 1);
		if(ch[u][c ^ 1]) {
			u = ch[u][c ^ 1];
			res |= (1 << i);
		} 
		else
			u = ch[u][c];
	}
	ans = max(ans, res);
}
void add(int u, int v, int w) {
	nxt[++ cnt] = head[u];
	head[u] = cnt;
	to[cnt] = v;
	weight[cnt] = w;
}
void dfs(int u, int fa) {
	insert(dis[u]);
	get(dis[u]);
	for(int i = head[u]; i; i = nxt[i]) {
		int v = to[i];
		if(v == fa) continue;
		dis[v] = dis[u] ^ weight[i];
		dfs(v, u);
	}
}
int main() {
	//freopen(".in","r",stdin);
	//freopen(".out","w",stdout);
	n = read();
	for(int i = 1; i < n; i ++) {
		int u, v, w;
		u = read(), v = read(), w = read();
		add(u, v, w); 
		add(v, u, w);
	}
	dfs(1, 0);
	write(ans), putchar('\n');
	return 0;
}

http://www.kler.cn/news/328049.html

相关文章:

  • 自然语言处理的应用领域有哪些?
  • 【漏洞复现】孚盟云oa AjaxSendDingdingMessage接口 存在sql注入漏洞
  • 云计算 Cloud Computing
  • 前端——DOM与BOM总结
  • macOS开发环境配置与应用
  • vant 数据校验
  • 华为OD机试 - 最长回文字符串 - 贪心算法(Python/JS/C/C++ 2024 E卷 100分)
  • ZYNQ: GPIO 之 MIO 控制 LED 实验
  • Qt(9.28)
  • 深入理解 `strtok()` 函数:字符串分割的艺术
  • go语言 常用的web框架
  • Ansible学习之ansible-pull命令
  • LLaMA: 开源大语言模型的革新者
  • react是一种语言?
  • PHP中的PEAR是什么
  • Metasploit渗透测试之服务端漏洞利用
  • 【基于spring-cloud-gateway实现自己的网关过滤器】
  • 通过 IPv6 进行远程 ADB 调试
  • 《RabbitMQ篇》基本概念介绍
  • 用于多模态MRI重建的具有空间对齐的深度展开网络|文献速递--基于多模态-半监督深度学习的病理学诊断与病灶分割
  • 基于C++和Python的进程线程CPU使用率监控工具
  • 【Linux 报错】“make: ‘xxxx‘ is up to date.” 解决办法
  • 红米k60至尊版工程固件 MTK芯片 资源预览 刷写说明 与nv损坏修复去除电阻图示
  • 第四届高性能计算与通信工程国际学术会议(HPCCE 2024)
  • 工程安全监测分析模型与智能算法模型方案
  • Shp2pb:Shapefile转Protocol Buffers的高效工具
  • 深度学习:DCGAN
  • 微信小程序——婚礼邀请函
  • 仪器数码管数字识别系统源码分享
  • 如何查看Linux系统类型