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

传送门

输入输出样例

输入样例#1:

5 7

1 2 2

1 3 2

2 4 1

2 5 1

4 5 3

5 3 4

4 3 2

输出样例#1:

6

说明

【样例说明】

根据异或的性质,将一个数异或两次便会消除影响

那么预处理所有环插入线性基中,之后随便(因为能够消除影响)找一条简单路径查询最大值即可

code:

//By Menteur_Hxy
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
#define LL long long
#define M(a,b) memset(a,(b),sizeof(a))
#define F(i,a,b) for(register int i=(a);i<=(b);i++)
#define C(i,a,b) for(register int i=(b);i>=(a);i--)
#define E(i,u) for(register int i=head[u];i;i=nxt[i])
using namespace std;

LL rd() {
    LL x=0,fla=1; char c=getchar();
    while(!isdigit(c)) {if(c==‘-‘) fla=-fla;c=getchar();}
    while(isdigit(c)) x=(x<<3)+(x<<1)+c-48,c=getchar();
    return x*fla;
}

const int N= 50010, M= 100010;
int n,m,ecnt;
int head[N],vis[N]; LL di[N];
int nxt[M<<1],to[M<<1]; LL dis[M<<1];
#define add(a,b,c) nxt[++ecnt]=head[a],to[ecnt]=b,head[a]=ecnt,dis[ecnt]=c

LL ba[70];
void insert(LL x) {
    for(int i=60;i>=0;i--) if(x>>i&1) {
        if(ba[i]) x^=ba[i];
        else {ba[i]=x;break;}
    }
}

LL query(LL x) {
    for(int i=60;i>=0;i--) if((x^ba[i])>x) x^=ba[i];
    return x;
}

void dfs(int u) {
    vis[u]=1;
    E(i,u) { int v=to[i];
        if(vis[v]) insert(di[u]^di[v]^dis[i]);
        else di[v]=di[u]^dis[i],dfs(v);
    }

}   

int main() {
    n=rd(); m=rd();
    F(i,1,m) {
        int a=rd(),b=rd(); LL c=rd();
        add(a,b,c); add(b,a,c);
    }
    dfs(1);
    printf("%lld",query(di[n]));
    return 0;
}

原文地址:https://www.cnblogs.com/Menteur-Hxy/p/9263371.html

时间: 2024-10-29 07:37:34

[luogu4151 WC2011] 最大XOR和路径 (线性基)的相关文章

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

题面 题面 题解 其实是一个很重要的套路啦. 首先我们从s到t的一个基础路径肯定是一条链,在此基础上,我们唯一可以带来一些增益的走法就是在走这条链的基础上走一些环,因为xor的特点,来回走的路都相当于没走,而只有环可以做到不往回走却能回到原点. 因此只有走环才会给原来的路线带来改变,否则走了都等于没走. 因此我们将图上所有简单环异或后的01串加入线性基. 那么对于一条指定的链,所以环可以带给它的最大增益可以用类似求最大异或和的方式来求. 所以我们还需要枚举每一条链? 其实不用. 因为所有链的起点

P4151 最大XOR和路径 线性基

题解见:https://www.luogu.org/problemnew/solution/P4151 其实就是找出所有环 把环上所有边异或起来得到的值扔到线性基里面 然后随便走一条从1~n的链 最后求最大异或和即可 #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define LL long long LL

NewTrain1 T9:[WC2011]最大XOR和路径

题目分析 我们把选出的路径看做一条1到n的简单路径+一些环 简单路径可以任取一条,就算我们选出的这条不是最优解的路径,我们也可以认为,我们走这条路径到了n,又走最优解的路径回到1,然后再走这条路径到n,这样其实就是这条路径+一个环,异或一下就抵消了这条路径. 那么对于一个不直接与这条路径联通的环,我们也可以认为这个环可以异或到答案里面.因为从这条路一条分岔出去到这个环,然后再原路返回,那从这条路到环的那段分岔异或一下就抵消掉了,所以可以直接异或这个环. 那么解题思路就是,预处理出所有的环,将其加

p4151 [WC2011]最大XOR和路径

分析 我们发现任取条路径 对于路径外的环一定可以将它完整的取到 而对于和路径有交的环相当于用一段新路径代替原来的一段路径 所以我们只需求出任意一个1到n的路径和图上所有环的值 然后借助线性基求出异或最大值即可 代码 #include<iostream> #include<cstdio> #include<cstring> #include<string> #include<algorithm> #include<cctype> #in

【2017西安邀请赛:A】XOR(线段树+线性基)

前言:虽然已经有很多题解了,但是还是想按自己的理解写一篇. 思路:首先分析题目 一.区间操作 —— 线段树 二.异或操作 —— 线性基 这个两个不难想,关键是下一步的技巧 “或”运算 就是两个数的二进制中,对应位 只要有1,那么就是该位结果就是 1,所以要想k“或”运算后的结果尽量大, 就需要异或出的数,各个位上的1尽量多. 线性基的操作,可以求出区间最大异或和,但是我们需要的结果是  “或”运算. 所以我们可以将 k 取反,然后把所有数在加入线性基之前,全部 “与”运算一遍,再加入线性基. 这

[HAOI2017]八纵八横 线性基

题面 题面 题解 观察到题目中的 "内陆经济环" 不好处理,因此我们把它拆成 "内陆经济链". 对于1号节点,我们创建一个它的复制节点n + 1号节点,这个节点继承1号节点的所有边,可以发现,一个1到1的内陆经济环,和一个1到n + 1的内陆经济链是等价的,因此我们只需要考虑如何在一个变化的图上维护一个点到另一个点的最大xor和即可. 观察到删边只会删去后来加入的边,所以就很好处理了,我们用线段树分治(时间分治)来维护. 具体求从1到n + 1的最大xor和的方法参

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和最大,所以必然我们要想办法处理环的情

线性基(一

1.线性基: 若干数的线性基是一组数a1,a2,...ana1,a2,...an,其中axax的最高位的11在第xx位. 通过线性基中元素xorxor出的数的值域与原来的数xorxor出数的值域相同. 2.线性基的构造法: 对每一个数pp从高位到低位扫,扫到第xx位为11时,若axax不存在,则ax=pax=p并结束此数的扫描,否则令p=pp=p   xorxor ax.ax. 3.查询: 用线性基求这组数xorxor出的最大值:从高往低扫axax,若异或上axax使答案变大,则异或. 4.判断

2115: [Wc2011] Xor (线性基+dfs)

2115: [Wc2011] Xor Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 5714  Solved: 2420 题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=2115 Description: Input: 第一行包含两个整数N和 M, 表示该无向图中点的数目与边的数目. 接下来M 行描述 M 条边,每行三个整数Si,Ti ,Di,表示 Si 与Ti之间存在 一条权值为 Di