洛谷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.寻找树中找两个结点,求最长的异或路径. 异或路径指的是指 ...
随机推荐
- scikit-learn入门导航
scikit-learn是一个非常强大的机器学习库, 提供了很多常见机器学习算法的实现. scikit-learn可以通过pip进行安装: pip install -U scikit-learn 不过 ...
- openssl x509(签署和自签署)
openssl系列文章:http://www.cnblogs.com/f-ck-need-u/p/7048359.html 主要用于输出证书信息,也能够签署证书请求文件.自签署.转换证书格式等. op ...
- [转]Angular4---部署---将Angular项目部署到IIS上
本文转自:https://www.cnblogs.com/kingkangstudy/p/7699710.html Angular项目部署到一个IIS服务器上 1.安装URL rewrite组件: 网 ...
- c# txt代码转换成HTML格式
/// <summary> /// 字符串字符处理 /// </summary> /// <param name="chr">等待处理的字符串& ...
- 菜鸟入门【ASP.NET Core】11:应用Jwtbearer Authentication、生成jwt token
准备工作 用VSCode新建webapi项目JwtAuthSample,并打开所在文件夹项目 dotnet new webapi --name JwtAuthSample 编辑JwtAuthSampl ...
- Python3.7 数字之间下划线
只是为了提高可读性,数值没变. >>> yes_votes = 42_572_6540 ; >>> yes_votes = 42_572_654099 ; > ...
- vb.net 日期時間
Dim dMyDate As DateTime = DateTime.Now‘當前時間日期 DateDiff("h", C13, C3)’ 二時間差 ‘日期格式 C2 = Form ...
- 访问WEB-INF下的jsp页面
访问web-inf下的jsp文件, 1)使用springMVC,一般都会使用springMVC的视图解析器,大概会这样配置 <!--jsp视图解析器--> <bean class ...
- CSS中的行内元素和块级元素
我们在构造页面时,会发现有的元素是上下排列的,而有的则是横向排列的,这是为啥子呢 看看上图,我们也没给他设置啥子属性咋就不一样了,其实是因为每个元素都有默认的 display 属性,比如 div ...
- html中用href 实现点击链接弹出文件下载对话框
浏览器支持能够打开的格式,他都会默认直接在线打开(比如word或图片),不支持的格式,他就会弹出下载提示.最好是做成.rar格式.xlsx的文件.浏览器自带下载功能. <body> < ...