题:https://www.luogu.com.cn/problem/P4151
题意:无向图找1到n路径异或和最大;
分析:可以不是简单路径,所以可以走出去再回来,而走出去走回来如果是链的话就是0了,那么是简单环的话答案的贡献就可以加上这个简单环的异或和;
所以我们可以把简单环的异或和扔到线性基里,然后考虑1到n的任意路径贡献为x;
接着考虑在线性基中从大到小异或上当前贡献x会不会更大,那么就异或上;
#include<bits/stdc++.h> using namespace std; typedef long long ll; #define pb push_back #define MP make_pair const int M=60; const int N=1e5+5; ll dis[N],vis[N]; vector< pair<int,ll> >g[N]; struct LB{ ll a[M+2]; vector<ll>vec; void init(){ for(int i=0;i<=M;i++) a[i]=0; vec.clear(); } void Insert(ll x){ for(int i=M;i>=0;i--){ if(!(x&(1ll<<i))) continue; if(a[i]) x^=a[i]; else{ for(int j=0;j<i;j++) if(x&(1ll<<j)) x^=a[j]; for(int j=i+1;j<=M;j++) if(a[j]&(1ll<<i)) a[j]^=x; a[i] = x; return ; } } } void getvec(){ for(int i=0;i<=M;i++) if(a[i]) vec.pb(a[i]); } ll getdis(ll x){ ll res=x; for(int i=vec.size()-1;i>=0;i--) { if((res^vec[i])>res) res^=vec[i]; } return res; } }lb; void dfs(int u,ll sum){ dis[u]=sum; vis[u]=1; for(auto it:g[u]){ int v=it.first; ll w=it.second; if(vis[v]) lb.Insert(sum^w^dis[v]); else dfs(v,sum^w); } } int main(){ int n,m; scanf("%d%d",&n,&m); lb.init(); for(int u,v,i=1;i<=m;i++){ ll w; scanf("%d%d%lld",&u,&v,&w); g[u].pb(MP(v,w)); g[v].pb(MP(u,w)); } dfs(1,0); lb.getvec(); printf("%lld ",lb.getdis(dis[n])); return 0; }