bzoj 2115 [Wc2011] Xor 路径最大异或和 线性基
题目链接
题意
给定一个 \(n(n\le 50000)\) 个点 \(m(m\le 100000)\) 条边的无向图,每条边上有一个权值。请你求一条从 \(1\)到\(n\)的路径,使得路径上的边的异或和最大。
题解
参考
https://blog.sengxian.com/algorithms/linear-basis
结论
答案=\(max_\{\)(某一条\(1\)到\(n\)的路径的异或和)\(\oplus\)(环\(i_1\)的异或和)\(\oplus\)(环\(i_2\)的异或和)...\(\}\)
构造性证明
我们证明,对于图中任意一个环,其异或和是可以取到的。
方法是从任意一个点\(u\)出发走到环上的某一点\(v\),绕一圈,然后再沿着\(v\)到\(u\)的路径原路返回,记路径\(u\rightarrow v\)的异或和为\(x_0\),环上的异或和为\(x_1\),则这一整段路的贡献即为\(x_0\oplus x_1\oplus x_0=x_1\),即为环上的异或和。
求值
现在的问题就转化为了,在线性基中取若干个向量,使得它们与某个初始给定值的异或和取到最大。
将向量从高位向低位逐个加入,使得和变大则加,否则不加,即可取到最大。
由线性基线性无关易见,对某一位的贡献只能来自于最多一个向量。
Code
#include <bits/stdc++.h>
#define maxn 200010
#define maxl 60
using namespace std;
typedef long long LL;
struct Edge { int to, ne; LL d; } edge[maxn<<1];
LL d[maxn], b[maxn];
int tot, ne[maxn], cnt;
bool vis[maxn];
void add(int u, int v, LL d) {
edge[tot] = {v, ne[u], d};
ne[u] = tot++;
edge[tot] = {u, ne[v], d};
ne[v] = tot++;
}
void dfs(int u, LL dd) {
d[u] = dd; vis[u] = true;
for (int i = ne[u]; ~i; i = edge[i].ne) {
int v = edge[i].to;
if (vis[v]) b[cnt++] = d[u] ^ edge[i].d ^ d[v];
else dfs(v, d[u] ^ edge[i].d);
}
}
struct LinearBasis {
LL a[maxl+1];
LinearBasis() { memset(a, 0, sizeof a); }
void insert(LL t) {
for (int i = maxl; i >= 0; --i) {
if (!(t >> i & 1)) continue;
if (a[i]) t ^= a[i];
else {
for (int j = 0; j < i; ++j) if (t >> j & 1) t ^= a[j];
for (int j = i+1; j <= maxl; ++j) if (a[j] >> i & 1) a[j] ^= t;
a[i] = t;
return;
}
}
}
LL condMax(LL t) {
LL ret = t;
for (int i = maxl; i >= 0; --i) {
if (!(a[i] >> i & 1)) continue;
if (ret >> i & 1) continue;
ret ^= a[i];
}
return ret;
}
};
int main() {
int n, m;
scanf("%d%d", &n, &m);
tot = 0; memset(ne, -1, sizeof ne);
for (int i = 0; i < m; ++i) {
int u, v; LL d;
scanf("%d%d%lld", &u, &v, &d);
add(u, v, d);
}
dfs(1, 0);
LinearBasis lb;
for (int i = 0; i < cnt; ++i) {
if (b[i]) lb.insert(b[i]);
}
printf("%lld\n", lb.condMax(d[n]));
return 0;
}
bzoj 2115 [Wc2011] Xor 路径最大异或和 线性基的更多相关文章
- bzoj 2115 [Wc2011] Xor——路径和环的转化
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2115 思路很精妙.好像能应用到很多地方. 发现如果路径上有环,可以通过一些走法达到 异或了那 ...
- BZOJ 2115: [Wc2011] Xor
2115: [Wc2011] Xor Time Limit: 10 Sec Memory Limit: 259 MB Submit: 2794 Solved: 1184 [Submit][Stat ...
- BZOJ 2115: [Wc2011] Xor DFS + 线性基
2115: [Wc2011] Xor Time Limit: 10 Sec Memory Limit: 259 MB Description Input 第一行包含两个整数N和 M, 表示该无向图中 ...
- bzoj 2115: [Wc2011] Xor xor高斯消元
2115: [Wc2011] Xor Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 797 Solved: 375[Submit][Status] ...
- BZOJ 2115 [Wc2011] Xor ——线性基
[题目分析] 显然,一个路径走过两边是不需要计算的,所以我么找到一条1-n的路径,然后向该异或值不断异或简单环即可. 但是找出所有简单环是相当复杂的,我们只需要dfs一遍,找出所有的环路即可,因为所有 ...
- BZOJ.2115.[WC2011]Xor(线性基)
题目链接 \(Description\) 给定一张无向带边权图(存在自环和重边).求一条1->n的路径,使得路径经过边的权值的Xor和最大.可重复经过点/边,且边权和计算多次. \(Soluti ...
- BZOJ 2115: [Wc2011] Xor 线性基 dfs
https://www.lydsy.com/JudgeOnline/problem.php?id=2115 每一条从1到n的道路都可以表示为一条从1到n的道路异或若干个环的异或值. 那么把全部的环丢到 ...
- bzoj 2115: [Wc2011] Xor【线性基+dfs】
-老是想到最长路上 其实可以这样:把每个环的xor和都存起来,然后任选一条1到n的路径的xor和ans,答案就是这个ans在环的线性基上跑贪心. 为什么是对的--因为可以重边而且是无相连通的,并且对于 ...
- BZOJ 2115 Wc2011 Xor DFS+高斯消元
标题效果:鉴于无向图.右侧的每个边缘,求一个1至n路径,右上路径值XOR和最大 首先,一个XOR并能为一个路径1至n简单的路径和一些简单的XOR和环 我们开始DFS获得随机的1至n简单的路径和绘图环所 ...
随机推荐
- 项目十八-Hadoop+Hbase分布式集群架构“完全篇”
本文收录在Linux运维企业架构实战系列 前言:本篇博客是博主踩过无数坑,反复查阅资料,一步步搭建,操作完成后整理的个人心得,分享给大家~~~ 1.认识Hadoop和Hbase 1.1 hadoop简 ...
- linux配置邮箱服务
配置邮箱服务Linux常见的邮箱客户端是mail或mutt:服务端有sendmail服务(centos 5).postfix服务(centos 6).这里我们不使用本地的邮件服务,而是使用本地的邮件客 ...
- 【CodeBase】通过层级键在多维数组中获取目标值
通过层级键在多维数组中获取目标值 /* *Author : @YunGaZeon *Date : 2017.08.09 *param data : Data Array *param keys : K ...
- DeepFaceLab报错,OOM如何解决?
DeepFaceLab出错,虽然错误提示好几个屏幕,但是无非两种情况,一种是驱动没装好,一种是显存配置不够.上一篇文章说了驱动的问题,这一篇就说说配置不够的问题. 这个问题的表现形式,往往是各种OOM ...
- python 正则表达式与JSON字符串
目录 正则表达式 概括单字符集 匹配单字符 匹配字符集 普通字符与元字符 元字符和普通的字符的混用 数量词{整数|*|+|?} 匹配指规则的字母 贪婪模式 匹配指定长度的字符串 非贪婪模式 匹配指定长 ...
- [BZOJ2331]地板(插头DP)
Description lxhgww的小名叫"小L",这是因为他总是很喜欢L型的东西.小L家的客厅是一个的矩形,现在他想用L型的地板来铺满整个客厅,客厅里有些位置有柱子,不能铺地板 ...
- Kubespray部署Kubernetes 1.13.0(使用本地镜像仓库)
1. 下载kubespray # git clone https://github.com/kubernetes-sigs/kubespray.git # cd kubespray # pip ins ...
- Android Kotlin适用小函数
都是一些Android适用的Kotlin小函数. 1.点击空白隐藏键盘 //点击空白隐藏键盘 override fun onTouchEvent(event: MotionEvent): Boolea ...
- leetcode 【 Plus One 】python 实现
题目: Given a non-negative number represented as an array of digits, plus one to the number. The digit ...
- IOS开发学习笔记008-预处理
预处理 1.宏定义 2.条件编译 3.文件包含 注意: 1.所有预处理都是以#开头,并且结尾不用分号. 2.宏名一般用大写字母,以便与变量名区别开来,但用小写也没有语法错误 3.作用域也是从定义到代码 ...