【线性基/神仙题】P4151 [WC2011]最大XOR和路径
Description
给定一个无向连通图,边有边权,求一个 \(1~\sim n\) 的路径,最大化边权的异或和。如果一条边经过多次则计算多次。
Input
第一行是两个整数 \(n,m\) 代表点数和边数
下面 \(m\) 行每行三个整数描述一条边
Output
输出一行一个整数代表答案
Hint
\(1~\leq~n~\leq~50000,1~\leq~m~\leq~100000,1~\leq~\) 边权 \(\leq~10^{18}\)
Solution
首先注意到一个结论:对于所有的简单环,环上边权的异或和都可以无代价的获取。原因是可以从一号点出发进入该环绕一圈后原路返回。由于一条路径绕两边对答案的贡献为 \(0\) ,所以这些简单环的异或和都可以无代价取得。那么现在问题就转化成了寻找一条 \(1\) 到 \(n\) 的路径,再异或上一些简单环的异或和,最大化答案。
我们考虑应该寻找哪一条路径:事实上任选一条路径即可。原因是选择的路径和答案路径一定可以构成一个环,所以异或上该环的权值就可以得到最优解。
考虑最大化异或和可以使用线性基解决。时间复杂度 \(O(m~+~n~\log^2d)\),其中 \(d\) 为边权
Code
#include <cstdio>
#include <algorithm>
#ifdef ONLINE_JUDGE
#define freopen(a, b, c)
#define printtime()
#else
#include <ctime>
#define printtime() printf("Times used = %ld ms\n", clock())
#endif
#define ci const int
#define cl const long long
typedef long long int ll;
namespace IPT {
const int L = 1000000;
char buf[L], *front=buf, *end=buf;
char GetChar() {
if (front == end) {
end = buf + fread(front = buf, 1, L, stdin);
if (front == end) return -1;
}
return *(front++);
}
}
template <typename T>
inline void qr(T &x) {
char ch = IPT::GetChar(), lst = ' ';
while ((ch > '9') || (ch < '0')) lst = ch, ch=IPT::GetChar();
while ((ch >= '0') && (ch <= '9')) x = (x << 1) + (x << 3) + (ch ^ 48), ch = IPT::GetChar();
if (lst == '-') x = -x;
}
template <typename T>
inline void ReadDb(T &x) {
char ch = IPT::GetChar(), lst = ' ';
while ((ch > '9') || (ch < '0')) lst = ch, ch = IPT::GetChar();
while ((ch >= '0') && (ch <= '9')) x = x * 10 + (ch ^ 48), ch = IPT::GetChar();
if (ch == '.') {
ch = IPT::GetChar();
double base = 1;
while ((ch >= '0') && (ch <= '9')) x += (ch ^ 48) * ((base *= 0.1)), ch = IPT::GetChar();
}
if (lst == '-') x = -x;
}
namespace OPT {
char buf[120];
}
template <typename T>
inline void qw(T x, const char aft, const bool pt) {
if (x < 0) {x = -x, putchar('-');}
int top=0;
do {OPT::buf[++top] = static_cast<char>(x % 10 + '0');} while (x /= 10);
while (top) putchar(OPT::buf[top--]);
if (pt) putchar(aft);
}
const int maxn = 50010;
const int maxm = 200010;
const int maxl = 61;
struct Edge {
int to;
ll v;
Edge *nxt;
};
Edge edge[maxm], *hd[maxn]; int ecnt;
inline void cont(ci from, ci to, cl v) {
Edge &e = edge[++ecnt];
e.to = to; e.nxt = hd[from]; e.v = v; hd[from] = &e;
}
int n, m;
ll ans;
bool vis[maxn];
ll val[maxn], lb[maxl];
void reading();
void insert(ll);
void dfs(ci, cl);
int main() {
freopen("1.in", "r", stdin);
qr(n); qr(m);
reading();
dfs(1, 0);
for (int i = maxl - 1; ~i; --i) {
ans = std::max(ans, ans ^ lb[i]);
}
qw(ans, '\n', true);
printtime();
return 0;
}
void reading() {
int a, b; ll c;
for (int i = 1; i <= m; ++i) {
a = 0; b = 0; c = 0; qr(a); qr(b); qr(c);
cont(a, b, c); cont(b, a, c);
}
}
void dfs(ci u, cl tp) {
vis[u] = true; val[u] = tp;
if (u == n) ans = tp;
for (Edge *e = hd[u]; e; e = e->nxt) {
int to = e->to;
if (!vis[to]) dfs(to, tp ^ e->v);
else insert(tp ^ e->v ^ val[to]);
}
}
void insert(ll x) {
for (int i = maxl - 1; ~i; --i) if (x & (1ll << i)) {
if (lb[i]) {
x ^= lb[i];
} else {
lb[i] = x;
for (int j = maxl - 1; j > i; --j) if (lb[j]) {
lb[j] ^= x;
}
for (int j = 0; j < i; ++j) if (lb[j] & (1ll << i)) {
lb[i] ^= lb[j];
}
break;
}
}
}
【线性基/神仙题】P4151 [WC2011]最大XOR和路径的更多相关文章
- 洛谷 P4151 [WC2011]最大XOR和路径 解题报告
P4151 [WC2011]最大XOR和路径 题意 求无向带权图的最大异或路径 范围 思路还是很厉害的,上午想了好一会儿都不知道怎么做 先随便求出一颗生成树,然后每条返祖边都可以出现一个环,从的路径上 ...
- P4151 [WC2011]最大XOR和路径
P4151 [WC2011]最大XOR和路径 一道妙极了的题. 首先直接从1走到n 然后现在图上有很多环 所以可以在走到n之后走到环上一个点,再走一遍环,再原路返回.这样就会xor上环的权值. 然后只 ...
- 洛谷P4151 [WC2011] 最大XOR和路径 [线性基,DFS]
题目传送门 最大XOR和路径 格式难调,题面就不放了. 分析: 一道需要深刻理解线性基的题目. 好久没打过线性基的题了,一开始看到这题还是有点蒙逼的,想了几种方法全被否定了.还是看了大佬的题解才会做的 ...
- 洛谷P4151 [WC2011]最大XOR和路径(线性基)
传送门 不知道线性基是什么东西的可以看看蒟蒻的总结 首先看到异或就想到线性基 我们考虑有一条路径,那么从这条路径走到图中的任意一个环再走回这条路径上,对答案的贡献是这个环的异或和,走到这个环上的路径对 ...
- [洛谷P4151][WC2011]最大XOR和路径
题目大意:给你一张$n$个点$m$条边的无向图,求一条$1->n$的路径,使得经过路径值的异或值最大(重复经过重复计算) 题解:某条路$k$被重复走了两次,那么它的权值对答案的贡献就是$0$,但 ...
- P4151 [WC2011]最大XOR和路径 线性基
题目传送门 题意:给出一幅无向图,求1到n的所有路径中最大异或和,一条边可以被重复经过. 思路: 参考了大佬的博客 #pragma GCC optimize (2) #pragma G++ optim ...
- [WC2011]最大XOR和路径(线性基)
P4151 [WC2011]最大XOR和路径 题目描述 XOR(异或)是一种二元逻辑运算,其运算结果当且仅当两个输入的布尔值不相等时才为真,否则为假. XOR 运算的真值表如下( 1 表示真, 0 表 ...
- [WC2011]最大XOR和路径 线性基
[WC2011]最大XOR和路径 LG传送门 需要充分发掘经过路径的性质:首先注意不一定是简单路径,但由于统计的是异或值,重复走是不会被统计到的,考虑对于任意一条从\(1\)到\(n\)的路径的有效部 ...
- 题解-[WC2011]最大XOR和路径
[WC2011]最大XOR和路径 给一个 \(n\) 个点 \(m\) 条边(权值为 \(d_i\))的无向有权图,可能有重边和子环.可以多次经过一条边,求 \(1\to n\) 的路径的最大边权异或 ...
随机推荐
- DevOps on AWS之Elastic BeanStalk
Elastic BeanStalk相关概念 童话世界中存在着一种魔力beanstalk(豆荚),种在花盆里可以无限的向上生长,越长越高直达云端.AWS Elastic Beanstalk也采用类似概念 ...
- python所遇到的坑
我是在ubuntu中,自带的有python2,python3有安装了anaconda套件,所以python的版本很多,曾经想删除过不用的python. 先执行 sudo apt remove pyth ...
- js备忘录5
函数的全解析 原文链接: http://mp.weixin.qq.com/s?src=11×tamp=1509672643&ver=491&signature=9fD ...
- map的运用
一.map是一种关联容器,支持高效的查找和访问 map中的元素是一些关键字-值(key-value)对: 关键字起索引作用: 值表示与索引相关联的数据. 关联容器中元素是根据关键字存储的,故其不支持位 ...
- Daily scrum 2015.10.19
这周是我们团队项目开始的第一周.我们的团队项目是“北航社团平台”,一个致力于打造北航社团资讯整合.社团工作服务与社团商品销售的一站式网络平台. 一.会议内容 1. 总体分工,江昊同学担任项目PM,王若 ...
- 奔跑吧DKY——团队Scrum冲刺阶段-Day 1-领航
各个成员在 Alpha 阶段认领的任务 修改 序号 修改 具体描述 1 游戏过程 取消原来的跳跃和俯身按钮,保留跳跃的功能,可以触屏滑动来躲避地面障碍物,也可以躲避另一种陷阱障碍物 2 闯关功能 取消 ...
- 20162314 《Program Design & Data Structures》Learning Summary Of The Seventh Week
20162314 2017-2018-1 <Program Design & Data Structures>Learning Summary Of The Seventh Wee ...
- 《大象Think in UML》阅读笔记之二
Think in UML阅读笔记(二) 上一次读到面向对象和面向过程的区别和各自的优势,结合实例分析了面向过程在面对大数据的时候,已经不足以满足人们的需求,所以引入了面向对象,面向对象的方法把世界看做 ...
- Reaction to 构造之法 of Software Engineering From The First Chapter toThe Fifth Chapter(补充版)
几个星期前,我阅读过一篇文章,一位老师教导自己的学生要积极地去阅读文学文献,其中,我很欣赏他的一句话:“Just think of liturature as if you're reading a ...
- cropper.js 超级好用的裁剪图片工具
最近要做一个照片裁剪功能.就选用了cropper.js 代码如下:贴出来 <div class="container"> <div class="row ...