【BZOJ2115】【Wc2011】 Xor 线性基 异或最长路

#include <stdio.h>
int main()
{
	puts("转载请注明出处谢谢");
	puts("http://blog.csdn.net/vmurder/article/details/43410545");
}

题意:找一条异或最长路。

题解:先随便来一条路径,然后我们发现这条路径上可以随便加简单环(不管有没有共点共边)、

就是因为可以先从某点走到环上来一圈再走回来,这样来去的路径被搞没了,简直污得不行。

然后我们可以用线性基来决定去异或哪些环。

并没有错。

算了来点干的吧,上面的都是在扯淡。

SARFT Warning:

5>>64=?

5>>65=?

我来告诉你! 分别是5和2!

那个英文是广电总局的意思。

所以大家注意线性基就安心扫到63得了,不要像我一样作死循环到65。

WA了好久啊!!!!!

代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 50100
#define M 101000
using namespace std;
struct KSD
{
	int v,next;
	long long len;
}e[M<<1];
int head[N],cnt;
inline void add(int u,int v,long long len)
{
	e[++cnt].v=v;
	e[cnt].len=len;
	e[cnt].next=head[u];
	head[u]=cnt;
}
int n,m;
bool vis[N];
long long d[N],a[M];
long long ins[70];
void dfs(int x)
{
	vis[x]=true;
	int i,v;
	for(i=head[x];i;i=e[i].next)
	{
		v=e[i].v;
		if(!vis[v])d[v]=d[x]^e[i].len,dfs(v);
		else a[++m]=d[v]^e[i].len^d[x];
	}
}
void Ins()
{
	int i,j;
	for(i=1;i<=m;i++)
	{
		for(j=63;j>=0;j--)
		{
			if((a[i]>>j)&1)
			{
				if(!ins[j])
				{
					ins[j]=a[i];
					break;
				}
				else a[i]^=ins[j];
			}
		}
	}
	long long ans=d[n];
	for(i=63;i>=0;i--)
		if((ans^ins[i])>ans)
			ans^=ins[i];
	printf("%lld\n",ans);
}
int main()
{
	freopen("test.in","r",stdin);

	int i,j;
	long long len;
	scanf("%d%d",&n,&m);
	while(m--)
	{
		scanf("%d%d%lld",&i,&j,&len);
		add(i,j,len),add(j,i,len);
	}
	dfs(1);
	Ins();
	return 0;
}
时间: 2024-10-07 11:18:31

【BZOJ2115】【Wc2011】 Xor 线性基 异或最长路的相关文章

【BZOJ-2115】Xor 线性基 + DFS

2115: [Wc2011] Xor Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 2142  Solved: 893[Submit][Status][Discuss] Description Input 第一行包含两个整数N和 M, 表示该无向图中点的数目与边的数目. 接下来M 行描述 M 条边,每行三个整数Si,Ti ,Di,表示 Si 与Ti之间存在 一条权值为 Di的无向边. 图中可能有重边或自环. Output 仅包含一个整数,表示最大

BZOJ 2115 [Wc2011] Xor ——线性基

[题目分析] 显然,一个路径走过两边是不需要计算的,所以我么找到一条1-n的路径,然后向该异或值不断异或简单环即可. 但是找出所有简单环是相当复杂的,我们只需要dfs一遍,找出所有的环路即可,因为所有的简单环都可以经过各种各样的异或得到. 然后线性基,在从高位向低位贪心即可,至于证明,需要拟阵的相关知识. [代码] #include <cstdio> #include <cstring> #include <cstdlib> #include <cmath>

BZOJ 2115: [Wc2011] Xor 线性基

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2115 解法: 膜:http://www.cnblogs.com/ljh2000-jump/p/5869925.html 这道题要求从1到n的最大xor和路径,存在重边,允许经过重复点.重复边.那么在图上作图尝试之后就会发现,路径一定是由许多的环和一条从1到n的路径组成.容易发现,来回走是没有任何意义的,因为来回走意味着抵消.考虑这道题求得是路径xor和最大,所以必然我们要想办法处理环的情

HDU 3949 XOR(线性基)

题意:给出一组数,求最小的第k个由这些数异或出来的数. 先求这组数的线性基.那么最小的第k个数显然是k的二进制数对应的线性基异或出来的数. # include <cstdio> # include <cstring> # include <cstdlib> # include <iostream> # include <vector> # include <queue> # include <stack> # includ

【HDU3949】XOR 线性基

#include <stdio.h> int main() { puts("转载请注明出处谢谢"); puts("http://blog.csdn.net/vmurder/article/details/43448493"); } 题意:给若干个数让你异或,然后询问第k大的异或和. 题解: 先搞出来线性基,然后第k大的异或和就是: 把k二进制拆分,第i位上有1,就把第i个线性基异或进来. 原因: 因为线性基是一堆高位上的1(或许有一些位动不了),然后把这

bzoj2115 [Wc2011] Xor——高斯消元 &amp; 异或线性基

题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2115 异或两次同一段路径的权值,就相当于没有走这段路径: 由此可以得到启发,对于不同的走法,也许只需要找出一些东西,就可以把所有的走法用它们来异或表示出来: 再关注图上的环路,因为从 1 到 n 的不同路径也可以看作是经由 1 和 n 连接的环路,路径上也可能有环路: 发现对于环路的不同走法,就是把路与环的权值异或求最优值,重叠的部分异或了两次相当于不走: 于是问题转化为找出图上的所有环(

HDU3949 XOR(线性基第k小)

Problem Description XOR is a kind of bit operator, we define that as follow: for two binary base number A and B, let C=A XOR B, then for each bit of C, we can get its value by check the digit of corresponding position in A and B. And for each digit,

[hdu3949]XOR(线性基求xor第k小)

题目大意:求xor所有值的第k小,线性基模板题. #include<cstdio> #include<cstring> #include<algorithm> #include<cstdlib> #include<iostream> #include<cmath> using namespace std; typedef long long ll; const int MAX_BASE=63; ll base[64],a[10006]

BZOJ 3105: [cqoi2013]新Nim游戏 [高斯消元XOR 线性基]

以后我也要用传送门! 题意:一些数,选择一个权值最大的异或和不为0的集合 终于有点明白线性基是什么了...等会再整理 求一个权值最大的线性无关子集 线性无关子集满足拟阵的性质,贪心选择权值最大的,用高斯消元判断是否和已选择的线性相关 每一位记录pivot[i]为i用到的行 枚举要加入的数字的每一个二进制为1的位,如果有pivot[i]那么就异或一下(消元),否则pivot[i]=这个数并退出 如果最后异或成0了就说明线性相关... #include <iostream> #include &l