[WC2011]最大XOR和路径

给一个 \(n\) 个点 \(m\) 条边(权值为 \(d_i\))的无向有权图,可能有重边和子环。可以多次经过一条边,求 \(1\to n\) 的路径的最大边权异或和。

数据范围:\(1\le n\le 5\cdot 10^4\),\(1\le m\le 10^5,0\le d_i\le 10^{18}\)。


非常神的一题,令小蒟蒻大开眼界。

一句话题解:通过 \(\texttt{Dfs}\) 得到到每个点的一种路径答案,用线性基找到最优替换方案。


先看这个奇奇怪怪的样例,样例解释中的最优路径等价于 \(1\to2\to5\to3\to4\to5\):

答案为 \(2\oplus1\oplus4\oplus2\oplus3=6\)。


有一种非常野蛮的做法是暴力 \(\texttt{Dfs}\) 整张无向图对每种答案求值,正确但是太慢。

但是考虑到异或运算的交换律,这是可以优化的,比如下图:

为了更好地说明问题,蒟蒻改了改样例图。

两条路径:

\(1\to4\to2\to3:3\oplus2\oplus4=5\)

\(1\to2\to4\to3\to5:2\oplus3\oplus2\oplus4=7\)

它们在 \(4\) 号点以后重合。根据异或的交换律和 \(x\oplus x=0\) 的性质可以得出两条路径的异或差(就是异或值)等于两条路径在 \(4\) 号点前的异或差。

即 \((3\oplus2\oplus4)\oplus(2\oplus3\oplus2\oplus4)=(3)\oplus(2\oplus3)=2\)

所以可以在 \(4\) 号点上记录下这个异或差 \(2\),然后选择一条路径继续走。等找到了其中一种到 \(n\) 的路径的异或和为 \(firstans\) 时,再看看 \(firstans\) 和 \(firstans\oplus2\) 谁大,如果 \(firstans<firstans\oplus2\) 则表示选到 \(4\) 号点的另一条路径更好。

于是这样遍历图就不需要遍历重复的点了,但是会在 \(\texttt{Dfs}\) 路径的交点处留下一堆异或差

若留下了 \(k\) 个异或差标记 \(c_i\),则答案有 \(2^k\) 种可能性。这时可以用一个线性基把所有异或差存起来,然后把 \(firstans\) 带进去得到最优答案。


小蒟蒻讲不清楚,所以再拿样例来解释:

蓝色路径为 \(\texttt{Dfs}\) 树,正好是条链。

\(firstans=2\oplus1\oplus3=0\),\(c_1=3\),\(c_2=5\),\(c_3=6\)。

丢进线性基:\(lb_0=0,lb_1=3,lb_2=5\)。

将 \(firstans=0\) 带入跑一趟,答案为 \(6\)。


时间复杂度 \(\Theta(m\log d)\)。


小蒟蒻又成功地写出了没人懂的题解,还是放代码吧:

#include <bits/stdc++.h>
using namespace std; //Start
typedef long long ll;
typedef double db;
#define mp(a,b) make_pair(a,b)
#define x(a) a.first
#define y(a) a.second
#define b(a) a.begin()
#define e(a) a.end()
#define sz(a) int((a).size())
#define pb(a) push_back(a)
const int inf=0x3f3f3f3f;
const ll INF=0x3f3f3f3f3f3f3f3f; //Data
const int N=5e4,M=2e5;
int n,m;
int E=-1;
vector<int> to;
vector<ll> w;
vector<int> e[N+7];
void add(int u,int v,ll d){
e[u].pb(++E),to.pb(v),w.pb(d);
e[v].pb(++E),to.pb(u),w.pb(d);
} //LB
const int LOGA=60;
ll lb[N+7];
void add(ll x){ //logn
for(int i=LOGA;i>=0;i--)if(x>>i){
if(lb[i]) x^=lb[i];
else return void(lb[i]=x);
}
}
ll find(ll x){ //logn
for(int i=LOGA;i>=0;i--)
if((x^lb[i])>x) x^=lb[i];
return x;
} //Bfs
int vis[N+7];
ll firstans[N+7];
void Dfs(int u,ll x){
vis[u]=1,firstans[u]=x;
for(int i:e[u])
if(!vis[to[i]]) Dfs(to[i],x^w[i]);
else add(firstans[to[i]]^(x^w[i])); //遇到交点,记录异或差
} //Main
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++){
int u,v; ll d;
scanf("%d%d%lld",&u,&v,&d);
add(u,v,d);
}
Dfs(1,0);
printf("%lld\n",find(firstans[n])); //得到一种路径异或和,替换寻优
return 0;
}

祝大家学习愉快!

题解-[WC2011]最大XOR和路径的更多相关文章

  1. [WC2011]最大XOR和路径(线性基)

    P4151 [WC2011]最大XOR和路径 题目描述 XOR(异或)是一种二元逻辑运算,其运算结果当且仅当两个输入的布尔值不相等时才为真,否则为假. XOR 运算的真值表如下( 1 表示真, 0 表 ...

  2. 洛谷 P4151 [WC2011]最大XOR和路径 解题报告

    P4151 [WC2011]最大XOR和路径 题意 求无向带权图的最大异或路径 范围 思路还是很厉害的,上午想了好一会儿都不知道怎么做 先随便求出一颗生成树,然后每条返祖边都可以出现一个环,从的路径上 ...

  3. [WC2011]最大XOR和路径 线性基

    [WC2011]最大XOR和路径 LG传送门 需要充分发掘经过路径的性质:首先注意不一定是简单路径,但由于统计的是异或值,重复走是不会被统计到的,考虑对于任意一条从\(1\)到\(n\)的路径的有效部 ...

  4. P4151 [WC2011]最大XOR和路径

    P4151 [WC2011]最大XOR和路径 一道妙极了的题. 首先直接从1走到n 然后现在图上有很多环 所以可以在走到n之后走到环上一个点,再走一遍环,再原路返回.这样就会xor上环的权值. 然后只 ...

  5. 洛谷P4151 [WC2011] 最大XOR和路径 [线性基,DFS]

    题目传送门 最大XOR和路径 格式难调,题面就不放了. 分析: 一道需要深刻理解线性基的题目. 好久没打过线性基的题了,一开始看到这题还是有点蒙逼的,想了几种方法全被否定了.还是看了大佬的题解才会做的 ...

  6. 洛谷 P4151 BZOJ 2115 [WC2011]最大XOR和路径

    //bzoj上的题面太丑了,导致VJ的题面也很丑,于是这题用洛谷的题面 题面描述 XOR(异或)是一种二元逻辑运算,其运算结果当且仅当两个输入的布尔值不相等时才为真,否则为假. XOR 运算的真值表如 ...

  7. [WC2011]最大XOR和路径(贪心+线性基)

    题目大意:给一张无向图,求一条1-n的路径,是路径边权的异或和最小. 题解 这道题的思路很妙,首先我们可以随便找出一条从1到n的路径来,然后我们可以选一些环. 其实不管这个环和这条路径有怎样的关系,我 ...

  8. [洛谷P4151][WC2011]最大XOR和路径

    题目大意:给你一张$n$个点$m$条边的无向图,求一条$1->n$的路径,使得经过路径值的异或值最大(重复经过重复计算) 题解:某条路$k$被重复走了两次,那么它的权值对答案的贡献就是$0$,但 ...

  9. luoguP4151 [WC2011]最大XOR和路径

    题意 这题有点神啊. 首先考虑注意这句话: 路径可以重复经过某些点或边,当一条边在路径中出现了多次时,其权值在计算 XOR 和时也要被计算相应多的次数 也就是说如果出现下面的情况: 我们可以通过异或上 ...

随机推荐

  1. 面试题:了解MySQL的Flush-List吗?顺便说一下脏页的落盘机制!(文末送书)

    Hi,大家好!我是白日梦! 今天我要跟你分享的MySQL话题是:"了解Flush-List吗?顺便说一下脏页的落盘机制!(文末送书)" 本文是MySQL专题的第 8 篇,共110篇 ...

  2. Java入门基础知识点总结(详细篇)

    Java入门基础知识点总结(详细篇)~~~~~目录 1.1 图解 1.1.1 Java基础知识点 1.1.2 Java基础语法的相关内容 1.2 关键字 1.3 标识符 1.3.1 标识符概念 1.3 ...

  3. Java POI导入word, 带图片

    1.导入文件示例,word中简历表格模板 2.代码示例分两部分,一部分读取图片 /** * 导入word(基本信息,word格式) * @param staffId * @param baseInfo ...

  4. JS中 `=+` 是什么?

    JS中 =+ 是什么? 依然是赋值 =是赋值,+代表后面的数字为正数,同理=-代表后面的数字为负数 用处 相当于告诉编译器,即将赋值的数值类型为数字类型,不要把数字当作字符串去拼接 示例 functi ...

  5. java 连接sqlserver

    db.properties 文件 driver=com.microsoft.sqlserver.jdbc.SQLServerDriver url=jdbc:sqlserver://10.1.1.19: ...

  6. 如何使用ABBYY FineReader 用户词典识别专业术语?

    ABBYY FineReader 15可以说是比较新的版本,在这个版本中能运用强大的光学字符识别技术对PDF文档扫描件.图像等文件进行OCR识别.在识别的过程中,会使用其内置的词典检查识别文字,以获得 ...

  7. 如何使用MindManager更改思维导图布局

    思维导图可以帮您直观地捕捉想法和信息,并将其组织起来,进一步创建行动计划,思维导图软件MindManager不仅可以帮您分析问题.使用头脑风暴得出解决方案,还可以规划复杂的项目.下面是MindMana ...

  8. Robot Framework安装和入门

    1:安装 python 安装python并且配置好环境变量 2:安装 Robot Framework pip install robotframework 3:安装GUI界面 pip install ...

  9. Codeforces Round #677 (Div. 3) E、G题解

    E. Two Round Dances #圆排列 题目链接 题意 \(n\)(保证偶数)个人,要表演一个节目,这个节目包含两种圆形舞蹈,而每种圆形舞蹈恰好需要\(n/2\)个人,每个人只能跳一种圆形舞 ...

  10. Java基础教程——封装

    面向对象的三大特征 封装:encapsulation 继承:inheritance 多态:polymorphism 封装 类是一个最基本的封装 封装的好处: 数据安全:保证数据安全 方便调用:提供清晰 ...