最小异或生成树(codeforces 888-G Xor-MST)

利用Boruvka's algorithm解决codeforces 888-G Xor-MST问题,通过01字典树进行贪心排序和处理,详细解释了如何在树形结构中找到最小异或生成树,包括左子树和右子树的最小异或生成树计算以及在合并子树时的最小代价求解方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最小异或生成树(codeforces 888-G Xor-MST)

原题: http://codeforces.com/contest/888/problem/G

题意给出2e5个点,边权为点权的异或,求最小生成树。

快去看看光巨巨的博客,比我这个明白多了(小声bb )

思路:对此题,可以立即想到暴力枚举的办法,但是复杂度远远超过题目要求。但是我们可以借鉴最小生成树中的常用的一种算法——Boruvka’s algorithm。即选择一条边权最小的边连接两个集合进行合并,直到没有集合可以再次合并。所以做这个题需要用到01字典树的相关知识。要按照字典树的贪心顺序,从上向下进行建树处理。确定子树里有哪些数时,可以在插入前就排序,记录每个节点的左右区间,枚举的时候直接枚举区间里的数即可。而根据贪心的思想,一个节点下的最小异或生成树=左子树的最小异或生成树+右子树的最小异或生成树+左子树和右子树合并时产生的最小代价。左子树和右子树的最小异或生成树可以用递归求解,但左右子树合并时最小代价如何求解呢?其实我们不妨可以遍历左子树的所有点,去右子树找一个异或起来最小的,再取min即可。找异或起来最小的也很容易,直接从上到下贪心即可(当然也可以遍历右子树然后去找左子树,两者都可以实现)。

代码
注意:数组开4e6或5e6都会TLE,我这里开的8e6(数组一定要开大一点)

#pragma GCC optimize(2)
#include<bits/stdc++.h> 
using namespace std;
typedef long long ll;
const int mod=1e9+7;
const int maxn=8e6+7;
const ll INF=1e18;
ll a[maxn],n;
struct f 
{
   
	ll node=0;
	ll Xor_trie[maxn][2];
	ll l[maxn],r[maxn]; //控制节点的左右区间
	void inint(){
   node=0;} //初始化操作
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值