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

洛谷P4551 最长异或路径(字典树,异或)

题目链接

https://www.luogu.com.cn/problem/P4551

思路

因为一个数同时对异或两个相同的数,其值不变。

因此我们很容易发现,对于节点 u u u与节点 v v v路径上的异或和可以表示为从根节点到 u u u的异或和异或上根节点到 v v v的异或和。

因此我们可以对根节点到每一个节点的异或和按照二进制的形式插入到 T r i e Trie Trie树上,最后贪心求得最终的答案即可。

时间复杂度: O ( 30 n ) O(30n) O(30n)

代码

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e5 + 5;
int n;
vector<int>v;
vector<pair<int, int>>mp[N];
struct Trie
{const int static maxn = 3e6 + 5;int son[maxn][2], idx;void insert(int x){int p = 0;for (int i = 30; i >= 0; i--){int &s = son[p][(x >> i) & 1];if (!s) s = ++idx;p = s;}}int query(int x){int res = 0, p = 0;for (int i = 30; i >= 0; i--){int bit = (x >> i) & 1;if (son[p][!bit]){res += (1ll << i);p = son[p][!bit];}else p = son[p][bit];}return res;}
} trie;
void dfs(int u, int fu, int sum)
{v.push_back(sum);for (int i = 0; i < mp[u].size(); i++){int j = mp[u][i].first;int w = mp[u][i].second;if (j == fu) continue;dfs(j, u, sum ^ w);}
}
void solve()
{cin >> n;for (int i = 1, u, v, w; i < n; i++){cin >> u >> v >> w;mp[u].push_back({v, w});mp[v].push_back({u, w});}dfs(1, -1, 0);for (int val : v){trie.insert(val);}int ans = 0;for (int val : v){ans = max(ans, trie.query(val));}cout << ans << endl;
}
signed main()
{ios::sync_with_stdio(false);cin.tie(0), cout.tie(0);int test = 1;// cin >> test;for (int i = 1; i <= test; i++){solve();}return 0;
}

http://www.mrgr.cn/news/35239.html

相关文章:

  • Node.JS有什么用?给谁用?怎么学?通俗易懂,超级详细!
  • vue脚手架Vue CLI 2.9.6创建工程,并引入elementUI的方法
  • C++STL--------string
  • Linux usb主机控制器HC阅读
  • scrapy spider框架download下来就可以用
  • DBeaver中如何导入excel中的大量数据
  • JS 特殊运算符有哪些?
  • 语言的变量交换
  • yolov10算法原理
  • rust一些通用编程的概念
  • js中Fucntion的意义
  • 语言的副作用
  • 打卡软件——人脸识别综合实现
  • Python NumPy学习指南:从入门到精通
  • 应用层 III(电子邮件)【★★】
  • Vue(16)——Vue3.3新特性
  • 最小花费爬楼梯(动态规划)问题
  • 工业一体机实现接口与模块选配
  • 【后端开发】JavaEE初阶—线程安全问题与加锁原理(超详解)
  • 3270.求出数字答案题解