You are given a complete undirected graph with n vertices. A number ai is assigned to each vertex, and the weight of an edge between vertices i and j is equal to aixoraj.

Calculate the weight of the minimum spanning tree in this graph.

题目大意:

边权为两端点点权的异或,求一个完全图的最小生成树

Input

The first line contains n (1 ≤ n ≤ 200000) — the number of vertices in the graph.

The second line contains n integers a1, a2, ..., an (0 ≤ ai < 230) — the numbers assigned to the vertices.

Output

Print one number — the weight of the minimum spanning tree in the graph.

Examples
Input

Copy
5
1 2 3 4 5
Output
8
Input

Copy
4
1 2 3 4
Output
8

本题要用到一种求生成树的方法Boruvka

给所有单词维护一颗trie树

按照这种求生成树的方法,我们每一次要在trie中去掉该集合的点,再求最小的边

这样很麻烦,实际上可以在trie树内部合并

首先左右子树中的所有点显然是已经在一个连通块内的。我们只需要在左右子树的联通块中各选出一
个点,连边即可

这样如果左子树存在右子树合并肯定最优,因为他们公共前缀最长

考虑启发式合并当前点的左右子树

枚举关键点数更小的子树的关键点,带入另一个子树求出最小边权

最后在根合并成一颗生成树

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
using namespace std;
typedef long long lol;
vector<lol>Q[];
int ch[][],pos,dep[],n;
lol pw[],ans,a[];
void insert(lol x)
{int i;
int now=;
Q[now].push_back(x);
for (i=;i>=;i--)
{
int flag=(bool)((x>>i)&);
if (ch[now][flag]==) ch[now][flag]=++pos;
now=ch[now][flag];
x-=flag*pw[i];
Q[now].push_back(x);dep[now]=i;
}
}
lol merge(int x,lol t)
{int i;
lol as=;
for (i=dep[x]-;i>=;i--)
{
int flag=(bool)((t>>i)&);
if (ch[x][flag]) x=ch[x][flag];
else as+=pw[i],x=ch[x][!flag];
}
return as;
}
lol query(int rt)
{int i;
if (Q[rt].size()==) return ;
if (ch[rt][]) ans+=query(ch[rt][]);
if (ch[rt][]) ans+=query(ch[rt][]);
if (!ch[rt][]||!ch[rt][]) return ;
int flag=;
if (Q[ch[rt][]].size()>Q[ch[rt][]].size()) flag=;
int sz=Q[ch[rt][flag]].size();
lol tmp=2e15;
for (i=;i<sz;i++)
tmp=min(tmp,merge(ch[rt][flag^],Q[ch[rt][flag]][i]));
return tmp+pw[dep[rt]-];
}
int main()
{int i;
cin>>n;
pw[]=;
for (i=;i<=;i++)
pw[i]=pw[i-]*;
for (i=;i<=n;i++)
{
scanf("%lld",&a[i]);
}
sort(a+,a+n+);
n=unique(a+,a+n+)-a-;
for (i=;i<=n;i++)
{
insert(a[i]);
}
ans+=query();
printf("%lld\n",ans);
}

首先左右子树中的所有点显然是已经在一个连通块内的。我们只需要在左右子树的联通块中各选出一
个点,连边即可

codeforces 888G Xor-MST的更多相关文章

  1. Codeforces.888G.Xor-MST(Borůvka算法求MST 贪心 Trie)

    题目链接 \(Description\) 有一张\(n\)个点的完全图,每个点的权值为\(a_i\),两个点之间的边权为\(a_i\ xor\ a_j\).求该图的最小生成树. \(n\leq2*10 ...

  2. Codeforces 888G Xor-MST - 分治 - 贪心 - Trie

    题目传送门 这是一条通往vjudge的高速公路 这是一条通往Codeforces的高速公路 题目大意 给定一个$n$阶完全图,每个点有一个权值$a_{i}$,边$(i, j)$的权值是$(a_{i}\ ...

  3. codeforces 22E XOR on Segment 线段树

    题目链接: http://codeforces.com/problemset/problem/242/E E. XOR on Segment time limit per test 4 seconds ...

  4. Xor-MST Codeforces - 888G

    https://codeforces.com/contest/888/problem/G 这题可以用Boruvka算法: 一开始每个点是一个连通块.每次迭代对于每个连通块找到其最近邻居(与其有边相连且 ...

  5. Codeforces 627A XOR Equation(思路)

    题目大概说两个正整数a.b,已知s=a+b以及x=a xor b的值,问有几种a.b这样的数对. 我知道异或相当于无进位的加法,s-x就是其各个位置的进位,比如s-x=1010,那就表示a和b的第1位 ...

  6. CodeForces 242E - XOR on Segment 二维线段树?

    今天练习赛的题....又是线段树的变换..拿到题我就敲了个点更新区间查询的..果断超时...然后想到了可以将每个数与合表示成不进位的二进制数..这样就可以区间进行更新了..比赛的时候写搓了..刚重写了 ...

  7. codeforces 242E. XOR on Segment 线段树

    题目链接 给n个数, 两种操作, 一种是求区间内的数的和, 一种是将区间内的数异或x. 异或x没有什么思路, 单个异或肯定超时, 区间异或也没有办法做....后来才知道可以按位建线段树, 这样建20棵 ...

  8. Codeforces 888G(分治+trie)

    按位贪心,以当前考虑位是0还是1将数分成两部分,则MST中这两部分之间只会存在一条边,因为一旦有两条或以上的边,考虑两条边在原图中所成的环,显然这两条边有一条是环上的权值最大边,不会出现在MST中.则 ...

  9. codeforces 242E - XOR on Segment (线段树 按位数建树)

    E. XOR on Segment time limit per test 4 seconds memory limit per test 256 megabytes input standard i ...

随机推荐

  1. C语言程序设计(基础)- 第6周作业

    一.PTA作业 完成PTA第六周作业中4个题目的思路列在博客中. 1.7-1 高速公路超速处罚 2.7-2 计算油费 3.7-3 比较大小 4.7-4 两个数的简单计算器 (必须使用switch结构实 ...

  2. 集大1513 & 1514班 软件工程第一次作业评分与点评

    谢谢大多数同学按时完成了作业,同学态度都比较端正,没有为了完成作业或者讨好老师而说一些假话空话. 很多同学选择CS之前并没有从兴趣或者擅长出发.这是一个普遍的现象,十年前我们是这样,十年后的孩子们还是 ...

  3. 项目Alpha冲刺Day12

    一.会议照片 二.项目进展 1.今日安排 修复全局的日期转换问题,完成用户所有相关的模块,对全局的异常处理做优化.其他模块进行一部分实现. 2.问题困难 全局异常处理后发现没有进行按照链进行下去,造成 ...

  4. DNS搜索过程

    以www.renyi.com为例 一:客户端首先检查本地HOST文件,是否有对应的IP地址,如果有,客户端直接访问,如果没有,则执行下一步. 二:客户端查看本地缓存信息,是否有对应的IP地址,如果有, ...

  5. 可空类型 Nullable<T>

    Nullable<T> 内部实现了显示和隐式转换 显示转换: public static explicit operator T(T? value) { return value.Valu ...

  6. BizTalk 2016 配置 RosettaNet遇到的坑

    本文只针对已经安装好BizTalk 2016 需要在安装RosettaNet加速器的伙伴. IIS配置 权限问题 错误信息 Failed to get IIS metabase property. E ...

  7. SendMessage 遇到的神坑

    场景 两个进程A和B,需要从A中设置B中的文本框的内容 过程 x.x.x.x. 成功获取了B中的内容,惊喜,离成功更近异步 xxxx ***** ....... x.x.x.x. 大约查找了几百个网页 ...

  8. Orm之中介模型

    什么是中介模型 中介模型针对的是ManyToMany(多对多)的时候第三张表的问题, 中介模型其实指的就是我们不通过Django创建第三张表,如果自己不创建第三张表,而是由django给我们创建,那就 ...

  9. POJ2318【判断点在直线哪一侧+二分查找区间】

    题目大意:给定一个矩形和一些线段,线段将矩形分割为从左至右的若干部分,之后给出一些玩具的坐标,求每个部分中玩具的数量 #include<cstdio> #include<cstdli ...

  10. python--同步锁/递归锁/协程

    同步锁/递归锁/协程 1 同步锁 锁通常被用来实现对共享资源的同步访问,为每一个共享资源创建一个Lock对象,当你需需要访问该资源时,调用acquire()方法来获取锁对象(如果其他线程已经获得了该锁 ...