• 题解 CF888G Xor-MST


    题意

    给定一张完全图,点有点权,边权定义为两端点的边权异或和,求最小生成树的边权和

    (nle 10^5)

    题解

    这是一张完全图,发现克鲁斯卡尔算法完全行不通,且我们不可能去处理出所有的边权

    考虑 借鉴 Boruvka 算法思想。就是将每一轮从连通块连出一条最小的通往其他连通块的边,并将两个连通块连在一起。可以发现最多只会进行(log n)

    重点在于求出每个连通块的最小出边。

    在这道题里面,我们可以用01trie 来维护连通块的最小出边,具体做法是每次找连通块在trie树上的另一个数使其异或值最小,复杂度(O(nlog n log a_i))

    再考虑一下我们是怎么合并两个连通块的,可以发现如若在trie树上一个节点存在分叉,那么就必然会是两个不同的联通块会在此处产生"连边"

    于是考虑从上到下遍历trie树,找出两个连通块的数的集合,然后求出最小出边即可,复杂度(O(nlog a))

    代码

    #include<bits/stdc++.h>
    using namespace std;
    int const MAXN=2e5+10;
    int n;
    int a[MAXN],L[MAXN*30],R[MAXN*30];
    struct Trie{
    	int tot=1;
    	int trie[MAXN*30][2];
    	void insert(int pos){
    		int x=1;
    		for(int i=30;;i--){
    			int dir=(a[pos]>>i)&1;
    			L[x]=min(L[x],pos),R[x]=max(R[x],pos);
    			if(i<0)break;
    			if(!trie[x][dir])trie[x][dir]=++tot;
    			x=trie[x][dir];
    		}
    		return;
    	}
    	long long query(int x,int now,int dep){
    		if(dep<0)return 0ll;
    		int dir=(x>>dep)&1;
    		if(trie[now][dir])return query(x,trie[now][dir],dep-1);
    		else return query(x,trie[now][dir^1],dep-1)+(1ll<<dep);
    	}
    	long long dfs(int now,int dep){
    		if(dep<0)return 0;
    		// printf("%d %d %d %d
    ",now,trie[now][0],trie[now][1],dep);
    		if(trie[now][0]&& trie[now][1]){
    			long long ans=1ll<<30;
    			// printf("%d %d
    ",L[trie[now][0]],R[trie[now][1]]);
    			for(int i=L[trie[now][0]];i<=R[trie[now][0]];i++){
    				ans=min(ans,(long long)query(a[i],trie[now][1],dep-1));
    			}
    			ans+=dfs(trie[now][0],dep-1);
    			ans+=dfs(trie[now][1],dep-1);
    			ans+=(1<<dep);
    			return ans;
    		}
    		else if(trie[now][0]){return dfs(trie[now][0],dep-1);}
    		else if(trie[now][1]){return dfs(trie[now][1],dep-1);}
    		return 0ll;
    	}
    }trie;
    int main(){
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    	sort(a+1,a+n+1);
    	memset(L,0x3f,sizeof(L));
    	for(int i=1;i<=n;i++)trie.insert(i);
    	printf("%lld
    ",trie.dfs(1,30));
    	return 0;
    }
    
  • 相关阅读:
    抽象类与抽象方法
    PCB设计铜铂厚度、线宽和电流关系
    单层或双层板(PCB)减少环路面积
    电源模块布局考虑因素总结
    传感器信号处理电路
    共模电压和差模电压
    采样电阻选型
    电源防反接保护电路
    MOSFET驱动电路
    自相关与偏自相关
  • 原文地址:https://www.cnblogs.com/fpjo/p/14584334.html
Copyright © 2020-2023  润新知