zoukankan      html  css  js  c++  java
  • 【题解】Acwing228. 异或

    Acwing228. 异或

    ( ext{Solution:})

    第一次见的套路 记录一下

    首先观察到路径,而且 (n) 很大,往最短路方面想,但是一个异或最大值就直接把最短路给干掉了

    考虑什么东西可以维护形如 选出一些数使得异或和最大 的问题?——线性基。

    那么重新分析题目,我们被要求找到一条路径满足异或和最大,而我们不知道如何决策是最优的……

    考虑分析一下最优答案的状态。我们发现,所有可能构成的答案的路径的并集中,必定有环。因为它们的起点终点都一样。

    而环又有什么性质?显然可以来回走对吧。这就让我们想起了对应于线性基上选不选的决策。

    那么,环现在是唯一自由的因素了。我们现在被要求选出一些数使得 (1) 可以通过它们到达 (n) 并且异或和最大化。

    而所有路径都会形成环,也就是说,每条路径都可以通过 异或上一个环 来转化为其他路径

    那这不就和用线性基维护环权值配对了吗。所以只需要 (dfs) 找环加上线性基维护贪心即可。

    复杂度 (O(nlog n)) 注意代码里面直接把线性基消成对角矩阵了。

    #include<bits/stdc++.h>
    using namespace std;
    #define int long long
    const int N=4e5+10;
    inline int read(){
    	int s=0;
    	char ch=getchar();
    	while(!isdigit(ch))ch=getchar();
    	while(isdigit(ch)){s=s*10+ch-'0';ch=getchar();}
    	return s;
    }
    int n,m,head[N],tot;
    struct E{int nxt,to,dis;}e[N];
    int val[N],vis[N];
    struct Line_Base{
    	int p[62];
    	void insert(int x){
    		for(int i=61;~i;--i){
    			int v=x>>i&1;
    			if(!v)continue;
    			if(p[i])x^=p[i];
    			else{
    				p[i]=x;
    				for(int j=i-1;~j;--j)if(p[i]>>j&1)p[i]^=p[j];
    				for(int j=61;j>i;--j)if(p[j]>>i&1)p[j]^=p[i];
    				return;
    			}
    		}
    	}
    	int query(int v){
    		for(int i=61;~i;--i)if((v^p[i])>v)v^=p[i];
    		return v;
    	}
    }U;
    inline void link(int x,int y,int w){e[++tot]=(E){head[x],y,w};head[x]=tot;}
    void dfs(int x){
    	vis[x]=1;
    	for(int i=head[x];i;i=e[i].nxt){
    		int j=e[i].to;
    		if(!vis[j]){
    			val[j]=val[x]^e[i].dis;
    			dfs(j);
    		}
    		else{
    			int v=val[x]^val[j]^e[i].dis;
    			if(!v)continue;
    			U.insert(v);
    		}
    	}
    }
    signed main(){
    	freopen("in.txt","r",stdin);
    	n=read();m=read();
    	for(int i=1;i<=m;++i){
    		int x=read(),y=read(),z=read();
    		link(x,y,z);link(y,x,z);
    	}
    	dfs(1);
    	printf("%lld
    ",U.query(val[n]));
    	return 0;
    }
    
  • 相关阅读:
    LeetCode113. 路径总和 II
    LeetCode257. 二叉树的所有路径
    LeetCode222. 完全二叉树的节点个数
    LeetCode404. 左叶子之和
    LeetCode110. 平衡二叉树
    LeetCode101. 对称二叉树
    LeetCode100. 相同的树
    llustrator CC2017下载AI2020
    vs code 代码格式化整理
    人生格言
  • 原文地址:https://www.cnblogs.com/h-lka/p/15378550.html
Copyright © 2011-2022 走看看