「WC2011」最大XOR和路径 做题记录
利用了 xor 两次为 \(0\) 的性质。
假设我们已经有了一条路径,要将其拓展至一条新的路径并更新答案,一种可能的拓展是存在一个环与该路径相交,就能将环上路径取反。
再仔细想想,其实不与该路径相交的环也是可以拓展的对象,完全可以从路径上某个点出发,进入该环,绕一圈,沿相同路径回来,
这样做前往环的一部分路径的贡献是重复了的,因此为 \(0\)。
观察这两种拓展,发现每次都可以将原本的路径异或上任意一个环。
相当于确定了一条路径之后,可以选择异或一些环,使异或和最大。可以用线性基搞定。
这条路径如何选择?
任意选即可,如果存在两条不同的路径,它们至少有两个点相交,所以一定存在环可以使两者相拓展。
那么直接把所有环的异或和扔到线性基里,加上任意一条 \(1\) 到 \(n\) 的路径求一下基可表达的最大值即可。
#include
#define fo(i,a,b) for(int i=a;i<=b;++i)
#define fd(i,a,b) for(int i=a;i>=b;--i)
#define ull unsigned long long
using namespace std;
const int N=5e4+10, M=1e5+10;
int n,m,tot,last[N];
bool bz[N];
struct edge{
int st,en,next;ull v;
}E[M<<1];
ull t[100],ans,dis[N];
void add(int x,int y,ull z){
E[++tot]=(edge){x,y,last[x],z};
last[x]=tot;
}
void insert(ull x){
fd(i,62,0)
if(x&(1ll<