洛谷P4551 最长异或路径
传送门:https://www.luogu.org/problem/show?pid=4551
在看这道题之前,我们应懂这道题怎么做:给定n个数和一个数m,求m和哪一个数的异或值最大。
一种很不错的做法是将n个数按二进制从最高位到低位建立一个trie树,然后把m放在trie树上跑一遍。
因为是从高位到低位存的,所以对于每一位,我们只要贪心让这一位的异或值得1。即如果m得当前位是1,就在trie树上找0;否则就找1.若能找到,ans的这一位就是1,否则是0.
如果上述这道水题会了的话,这道题就不难想了。
首先预处理每一个点到根节点的异或距离,为什么这么做呢,看下图

比如点7到根节点的距离dis[7] = f ^ b ^ a,点6到根节点的距离dis[6] = c ^ a,则dis[7] ^ dis[6] = f ^ b ^ c ^ a ^ a = f ^ b ^ c,恰好为6到7的距离。
因此我们就可以像上面这道题一样,将所有dis放到trie树里面,然后再让每一个dis[i]跑一遍trie树,最后结果取max即可。
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<iostream>
#include<queue>
#include<vector>
#include<cctype> //isdigit
using namespace std;
typedef long long ll;
#define enter printf("\n")
const int maxn = 1e5 + ;
const int INF = 0x3f3f3f3f;
inline ll read() {
ll ans = ;
char ch = getchar(), last = ' ';
while(!isdigit(ch)) {
last = ch;
ch = getchar();
}
while(isdigit(ch)) {
ans = ans * + ch - '';
ch = getchar();
}
if(last == '-') ans = -ans;
return ans;
}
inline void write(ll x) {
if(x < ) {
putchar('-');
x = -x;
}
if(x == ) {
putchar('');
return;
}
int q[], N = ;
q[] = ;
while(x) {
q[++N] = x % ;
x /= ;
}
while(N) {
putchar('' + q[N]);
--N;
}
} int n;
vector<int> v[maxn], c[maxn];
int cost[maxn];
bool vis[maxn];
void bfs(int s) { //bfs预处理每一个点到根节点的距离
queue<int> q;
q.push(s);
vis[s] = ;
cost[s] = ;
while(!q.empty()) {
int now = q.front();
q.pop();
for(int i = ; i < (int)v[now].size(); ++i) {
if(!vis[v[now][i]]) {
vis[v[now][i]] = ;
cost[v[now][i]] = cost[now] ^ c[now][i];
q.push(v[now][i]);
}
}
}
}
struct Trie {
int ch[maxn * ][], tot;
Trie() {
memset(ch, , sizeof(ch));
tot = ;
}
void Insert(int x) { //建树
int now = ;
for(int i = ; i >= ; --i) {
int w = (x >> i) & ;
if(!ch[now][w]) ch[now][w] = ++tot;
now = ch[now][w];
}
}
int query(int x) {
int now = , ret = ;
for(int i = ; i >= ; --i) {
int w = (x >> i) & ;
if(!ch[now][!w]) now = ch[now][w];
else {
now = ch[now][!w]; //若和x这一位不同的边存在,就走这条边,同时ret的这一位标记成1
ret += ( << i);
}
}
return ret;
}
} trie; int ans = ; int main() {
n = read();
for(int i = ; i < n; ++i) {
int a = read(), b = read(), cost = read();
v[a].push_back(b);
c[a].push_back(cost);
v[b].push_back(a);
c[b].push_back(cost);
}
bfs();
for(int i = ; i <= n; ++i)
trie.Insert(cost[i]);
for(int i = ; i <= n; ++i)
ans = max(ans, trie.query(cost[i]));
write(ans);
enter;
return ;
}
洛谷P4551 最长异或路径的更多相关文章
- 洛谷 P4551 最长异或路径
题目描述 给定一棵 nn 个点的带权树,结点下标从 11 开始到 NN .寻找树中找两个结点,求最长的异或路径. 异或路径指的是指两个结点之间唯一路径上的所有节点权值的异或. 输入输出格式 输入格式: ...
- 2018.10.26 洛谷P4551 最长异或路径(01trie)
传送门 直接把每个点到根节点的异或距离插入01trie. 然后枚举每个点在01trie上匹配来更新答案就行了. 代码: #include<iostream> #include<cst ...
- [luogu] P4551 最长异或路径(贪心)
P4551 最长异或路径 题目描述 给定一棵\(n\)个点的带权树,结点下标从\(1\)开始到\(N\).寻找树中找两个结点,求最长的异或路径. 异或路径指的是指两个结点之间唯一路径上的所有边权的异或 ...
- P4551 最长异或路径
题目描述 给定一棵 nnn 个点的带权树,结点下标从 111 开始到 NNN .寻找树中找两个结点,求最长的异或路径. 异或路径指的是指两个结点之间唯一路径上的所有边权的异或. 输入输出格式 输入格式 ...
- P4551 最长异或路径 (01字典树,异或前缀和)
题目描述 给定一棵 n 个点的带权树,结点下标从 1 开始到 N .寻找树中找两个结点,求最长的异或路径. 异或路径指的是指两个结点之间唯一路径上的所有边权的异或. 输入输出格式 输入格式: 第一行一 ...
- Luogu P4551 最长异或路径
题目链接 \(Click\) \(Here\) \(01Trie\)好题裸题. 取节点\(1\)为根节点,向下扫每一个点从根节点到它路径上的异或和,我们可以得到一个\(sumx[u]\). 现在路径异 ...
- Luogu P4551 最长异或路径 01trie
做一个树上前缀异或和,然后把前缀和插到$01trie$里,然后再对每一个前缀异或和整个查一遍,在树上从高位向低位贪心,按位优先选择不同的,就能贪出最大的答案. #include<cstdio&g ...
- luoguP4551最长异或路径
P4551最长异或路径 链接 luogu 思路 从\(1\)开始\(dfs\)求出\(xor\)路径.然后根据性质\(x\)到\(y\)的\(xor\)路径就是\(xo[x]^xo[y]\) 代码 # ...
- 【ybt高效进阶2-4-3】【luogu P4551】最长异或路径
最长异或路径 题目链接:ybt高效进阶2-4-3 / luogu P4551 题目大意 给定一棵 n 个点的带权树,结点下标从 1 开始到 N.寻找树中找两个结点,求最长的异或路径. 异或路径指的是指 ...
随机推荐
- ZooKeeper 分布式锁
在Redis分布式锁一文中, 作者介绍了如何使用Redis开发分布式锁. Redis分布式锁具有轻量高吞吐量的特点,但是一致性保证较弱.我们可以使用Zookeeper开发分布式锁,来满足对高一致性的要 ...
- VirtualBox centos7扩容
有时候扩容还真不如重新建立一个大硬盘的系统,但是如果你安装了好多东西的话,那还是来扩容一下吧. 查看磁盘格式 在virtualBox中右键点击虚拟机->设置->存储,如 ...
- [转]group by 后使用 rollup 子句总结
group by 后使用 rollup 子句总结 一.如何理解group by 后带 rollup 子句所产生的效果 group by 后带 rollup 子句的功能可以理解为:先按一定的规则产生多种 ...
- ModBus通信协议的【功能码】
Modbus的功能码 ModBus 功能码与数据类型对应表: RTU 方式读取整数据的例子: 解析一下:主机发送指令,访问从站地址为1,使用功能码03(读保持寄存器),起始地址高8位.低8位 ...
- mysql允许所有机器访问
1.进入到MySQL安装的bin目录. 2.运行mysql -uroot 3. 授权用户,你想root使用密码从任何主机连接到mysql服务器 GRANT ALL PRIVILEGES ON *.* ...
- spark_wordcount
spark是基于scala写的,虽然spark有java API,或者python API,但是scala算是正统吧. 而且scala的语法书写起来十分的爽,不想java那样笨重,python不太了解 ...
- 【 js 工具 】如何使用Git上传本地项目到github?(mac版)
在此假设你已经在 github 上创建好了一个项目,像这样: 并且你已经完成了自己的项目代码, 同时你也已经安装了 git,然后 let's start. 首先,建一个文件夹比如文中演示的是 微信小程 ...
- element-ui Carousel 走马灯源码分析整理笔记(十一)
Carousel 走马灯源码分析整理笔记,这篇写的不详细,后面有空补充 main.vue <template> <!--走马灯的最外层包裹div--> <div clas ...
- 微信小程序地图报错——ret is not defined
刚刚在使用微信的map做地图时候 发现如下报错: 后来找了一会发现错误为经纬度写反了导致经纬度超出了范围 正确取值范围: latitude 纬度 浮点数,范围 -90 ~ 90 longitud ...
- rem与px之间的换算(移动端)
最近因为工作接触到rem与px之间的换算,之前知道一些,不过还是比较笼统模糊,用起来不是很明白,后来自己查了点资料,以及亲自测试总算明白它们之间是怎么换算的了. rem是一个相对值,它相对于根元素ht ...