www.lydsy.com/JudgeOnline/problem.php?id=2115 (题目链接)

题意

  给出一张图,可能有重边和自环,在图中找出一条从1~n的路径,使得经过的路径的权值的异或和最大,每条边可以重复经过并且重复计算异或和。

Solution

  刚看到这道题,想了10分钟完全没有思路,于是就膜了题解。

  我们先把图看成一棵树,那么我们所需要找出的路径可以分成一些环和一条从1~n的树上路径,至于树是怎么构造的以及那条从1~n的路径是怎么走的并不重要,因为我们可以通过在总路径上补环来增大异或和。于是这个问题就转化为了如何在环的异或和中选出一些使得这些值异或上从1~n的路径的异或和最大。

  于是我们先dfs一遍把环以及它的异或和抠出来,当然这些环可能并不完全,但它们可以通过互相异或来异或出没有得到的环。如果发现当前节点x的目标节点e[i].to已经被走过了,那么这个环的异或和就是${dis[x]~XOR~dis[e[i].to]~XOR~e[i].w}$。

  怎么求最大异或和呢?这需要用到一个很神的东西:线性基

  什么是线性基:

  若干数的线性基是一组数a1,a2,…an,其中ax的最高位的1在第x位。通过线性基中元素xor出的数的值域与原来的数xor出数的值域相同。 
  线性基主要有2个优秀的性质: 
  可以O(k)(二进制的位数)的求出能异或出的最大值,或者是判断一个数能否被异或出来。

  线性基的构造:

  线性基的构造有两种: 
  第一是高斯消元。通过高斯消元将二进制矩阵消成上三角矩阵或者是对角矩阵,当然消成后者时间复杂度略高,但也更为方便,求解异或和最大时一路for下去就可以了。而上三角矩阵需要判断如果答案异或上这个值能否使答案增大。 
  第二种就是一种拟阵贪心,详情参见jump大爷的博客——www.cnblogs.com/ljh2000-jump/p/5869991.html,因为证明太高深,这里也就不再赘述。

  所以这道题就很好做了对吧,这里我选择消成对角矩阵,性质就更加显然一些。

代码

// bzoj2115
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
#define LL long long
#define inf 2147483640
#define Pi 3.1415926535898
#define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
using namespace std; const int maxn=50010,maxm=100010;
struct edge {int to,next;LL w;}e[maxm<<1];
LL dis[maxn],c[maxm<<2],bin[65];
int vis[maxn],n,m,tot,sum,cnt,head[maxn]; void link(int u,int v,LL w) {
e[++cnt].to=v;e[cnt].next=head[u];head[u]=cnt;e[cnt].w=w;
e[++cnt].to=u;e[cnt].next=head[v];head[v]=cnt;e[cnt].w=w;
}
void dfs(int x) {
vis[x]=1;
for (int i=head[x];i;i=e[i].next) {
if (!vis[e[i].to]) {
dis[e[i].to]=dis[x]^e[i].w;
dfs(e[i].to);
}
else c[++sum]=dis[x]^dis[e[i].to]^e[i].w;
}
}
void Gauss() {
for (LL i=bin[60];i;i>>=1) {
int j=tot+1;
while (j<=sum && !(c[j]&i)) j++;
if (j==sum+1) continue;
swap(c[++tot],c[j]);
for (j=1;j<=sum;j++) if (j!=tot && c[j]&i) c[j]^=c[tot];
//for (int k=j+1;k<=sum;k++) if (c[k]&i) c[k]^=c[tot];
}
}
int main() {
bin[0]=1;for (int i=1;i<=60;i++) bin[i]=bin[i-1]<<1;
scanf("%d%d",&n,&m);
for (int u,v,i=1;i<=m;i++) {
LL w;
scanf("%d%d%lld",&u,&v,&w);
link(u,v,w);
}
dfs(1);
Gauss();
LL ans=dis[n];
for (int i=1;i<=tot;i++) ans=max(ans,ans^c[i]);
printf("%lld\n",ans);
return 0;
}

  

【bzoj2115】 Xor的更多相关文章

  1. 【BZOJ2115】Xor(线性基)

    [BZOJ2115]Xor(线性基) 题面 BZOJ Description Input 第一行包含两个整数N和 M, 表示该无向图中点的数目与边的数目. 接下来M 行描述 M 条边,每行三个整数Si ...

  2. 【BZOJ-2115】Xor 线性基 + DFS

    2115: [Wc2011] Xor Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 2142  Solved: 893[Submit][Status] ...

  3. 【BZOJ2115】[Wc2011] Xor 高斯消元求线性基+DFS

    [BZOJ2115][Wc2011] Xor Description Input 第一行包含两个整数N和 M, 表示该无向图中点的数目与边的数目. 接下来M 行描述 M 条边,每行三个整数Si,Ti ...

  4. 【BZOJ2337】Xor和路径(高斯消元)

    [BZOJ2337]Xor和路径(高斯消元) 题面 BZOJ 题解 我应该多学点套路: 对于xor之类的位运算,要想到每一位拆开算贡献 所以,对于每一位拆开来看 好了,既然是按位来算 我们就只需要计算 ...

  5. 【bzoj2115】[Wc2011] Xor

    2115: [Wc2011] Xor Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 2512  Solved: 1049[Submit][Status ...

  6. 【HDU3949】XOR

    [题目大意] 给定一个数组,求这些数组通过异或能得到的数中的第k小是多少. 传送门:http://vjudge.net/problem/HDU-3949 [题解] 首先高斯消元求出线性基,然后将k按照 ...

  7. 【bzoj2115】【wc2011】Xor

    2115: [Wc2011] Xor Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 5380  Solved: 2249[Submit][Status ...

  8. bzoj2115【WC2001】Xor

    2115: [Wc2011] Xor Time Limit: 10 Sec  Memory Limit: 259 MB Submit: 2059  Solved: 856 [Submit][Statu ...

  9. 【bzoj2115】[Wc2011] Xor DFS树+高斯消元求线性基

    题目描述 输入 第一行包含两个整数N和 M, 表示该无向图中点的数目与边的数目. 接下来M 行描述 M 条边,每行三个整数Si,Ti ,Di,表示 Si 与Ti之间存在 一条权值为 Di的无向边. 图 ...

随机推荐

  1. 为Unity项目生成文档(一)

    VS生成chm帮助文档 VS代码中使用Xml注释,并通过Sandcastle生成chm文档的文章,这几篇值得分享: 使用.NET中的XML注释(一) -- XML注释标签讲解 使用.NET中的XML注 ...

  2. 学员信息录入(StuInfoManager) 用分层实现(既MySchool后的一个案例)

    数据库 数据表名 Student 中文表名 学员信息表 字段显示 字段名 数据类型 字段大小 备注和说明 编号 stu_id int 主键,自增1 学生姓名 stu_name varchar 50 不 ...

  3. java 21 - 11 IO流的标准输入流和标准输出流

    标准输入输出流 System类中的两个成员变量: public static final InputStream in "标准"输入流. public static final P ...

  4. 基于 URL 的权限控制

    先不用框架,自己实现一下 数据库 /* SQLyog v10.2 MySQL - 5.1.72-community : Database - shiro *********************** ...

  5. 28Spring_的事务管理_银行转账业务加上事务控制_基于注解进行声明式事务管理

    将applicationContext.xml 和 AccountServiceImpl 给备份一个取名为applicationContext2.xml 和 AccountServiceImpl2.j ...

  6. [Elixir007] on_definition规范函数定义时的各种潜规则

    1.需求 写一个基于memcache的cache模块, 需要在key前面加上特定的前缀, 所以user cache的原始的store函数应该写成 # user.exdef store(user_id, ...

  7. [转]reids客户端 redis-cli用法

    连接:redis-cli -h machine -p port -n db转的:每次都搜,还是扔在这 Redis提供了丰富的命令(command)对数据库和各种数据类型进行操作,这些command可以 ...

  8. js 中常用的方法

    1..call() 将.call()点之前的属性或方法,继承给括号中的对象. 2.(function(){xxx})() 解释:包围函数(function(){})的第一对括号向脚本返回未命名的函数, ...

  9. 实现chrome扩展启动本地进程 - 补充

    实现chrome扩展启动本地进程 - 补充 标签: chrome扩展启动本地程序访问本地磁盘 2014-10-17 11:42 6753人阅读 评论(17) 收藏 举报  分类: Chrome Plu ...

  10. [CareerCup] 13.5 Volatile Keyword 关键字volatile

    13.5 What is the significance of the keyword "volatile" in C 这道题考察我们对于关键字volatile的理解,顾名思义, ...