CF888G Xor-MST 解题报告
CF888G Xor-MST
题意翻译
给定一个\(n\)个节点的完全图,每个节点有个编号\(a_i\),节点\(i\)和节点\(j\)之间边的权值为\(a_i\ xor\ a_j\),求该图的最小生成树的权值和。
说明
\(1\le n \le 200000,0\le a_i< 2^{30}\)
有一种B开头的MST算法
大致流程是这样的
当前每个集合伸出去一条最短的边,然后把联通块缩成一个新的集合,因为每次缩集合个数减半,所以复杂度对。
事实上基本不会让我们真去写它,有时候需要用这种方法或者思想处理处MST。
比如这个题就可以这么做,每次合并实际上对trie树做启发式合并,然后在里面查一下最小值。
然后有一种神奇的思路,这里sto attack巨佬
发现每次合并的集合都是最高位的1不同的两个集合进行合并,于是可以从上往下做,从最高位把集合分开,然后查询两个集合的最小连边。
如果我们把所有元素按从小到大排序加入trie,那么一个集合内的元素就在一个连续的区间里啦
这样我们就可以非常方便的直接遍历一遍字典树统计出答案了
Code:
#include <cstdio>
#include <cstring>
#include <algorithm>
#define ll long long
using std::min;
using std::max;
const int N=2e5+10;
const int inf=0x3f3f3f3f;
#define ls ch[now][0]
#define rs ch[now][1]
int L[N*40],R[N*40],ch[N*40][2],tot;
int n,a[N],root;
void Insert(int &now,int x,int dep)
{
if(!now) now=++tot;
L[now]=min(L[now],x),R[now]=max(R[now],x);
if(dep<0) return;
int bit=a[x]>>dep&1;
Insert(ch[now][bit],x,dep-1);
}
int query(int now,int val,int dep)
{
if(dep<0) return 0;
int bit=val>>dep&1;
if(ch[now][bit]) return query(ch[now][bit],val,dep-1);
else return query(ch[now][bit^1],val,dep-1)+(1<<dep);
}
ll dfs(int now,int dep)
{
if(dep<0) return 0;
if(R[ls]&&R[rs])
{
int mi=inf;
for(int i=L[ls];i<=R[ls];i++) mi=min(mi,query(rs,a[i],dep-1));
return dfs(ls,dep-1)+dfs(rs,dep-1)+mi+(1<<dep);
}
if(R[ls]) return dfs(ls,dep-1);
if(R[rs]) return dfs(rs,dep-1);
return 0;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",a+i);
std::sort(a+1,a+1+n);
memset(L,0x3f,sizeof(L));
for(int i=1;i<=n;i++) Insert(root,i,30);
printf("%lld\n",dfs(root,30));
return 0;
}
2019.1.4
CF888G Xor-MST 解题报告的更多相关文章
- HDU4825:Xor Sum 解题报告(0/1 Trie树)
Problem Description Zeus 和 Prometheus 做了一个游戏,Prometheus 给 Zeus 一个集合,集合中包含了N个正整数. 随后 Prometheus 将向 Ze ...
- 人生第一场CTF的解题报告(部分)
解题报告 濮元杰部分: 王者归来: 120 场景 小王入职了一段时间,最近有点无聊.Web安全项目不多,白天看着其他项目组的同事忙得热火朝天,小王有点坐不住了,这也许是新人都会有的想法,乐于助人.想到 ...
- 冲刺Noip2017模拟赛5 解题报告——五十岚芒果酱
1. 公约数(gcd) [问题描述] 给定一个正整数,在[,n]的范围内,求出有多少个无序数对(a,b)满足 gcd(a,b)=a xor b. [输入格式] 输入共一行,一个正整数n. [输出格式] ...
- ZROI Day1 比赛解题报告
ZROI Day1 比赛解题报告 版权原因不提供题面相关信息 序 前天晚上搞得比较晚,然后早上做题很没状态,刚看到T1发现没什么思路就有点慌,赶紧看了看T2,T3, 发现T3暴力很好打,T2想了一想可 ...
- 【剑指Offer】数组中只出现一次的数字 解题报告(Python)
[剑指Offer]数组中只出现一次的数字 解题报告(Python) 标签(空格分隔): 剑指Offer 题目地址:https://www.nowcoder.com/ta/coding-intervie ...
- CH Round #56 - 国庆节欢乐赛解题报告
最近CH上的比赛很多,在此会全部写出解题报告,与大家交流一下解题方法与技巧. T1 魔幻森林 描述 Cortana来到了一片魔幻森林,这片森林可以被视作一个N*M的矩阵,矩阵中的每个位置上都长着一棵树 ...
- 二模13day1解题报告
二模13day1解题报告 T1.发射站(station) N个发射站,每个发射站有高度hi,发射信号强度vi,每个发射站的信号只会被左和右第一个比他高的收到.现在求收到信号最强的发射站. 我用了时间复 ...
- BZOJ 1051 最受欢迎的牛 解题报告
题目直接摆在这里! 1051: [HAOI2006]受欢迎的牛 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 4438 Solved: 2353[S ...
- 习题:codevs 2822 爱在心中 解题报告
这次的解题报告是有关tarjan算法的一道思维量比较大的题目(真的是原创文章,希望管理员不要再把文章移出首页). 这道题蒟蒻以前做过,但是今天由于要复习tarjan算法,于是就看到codevs分类强联 ...
- 习题:codevs 1035 火车停留解题报告
本蒟蒻又来写解题报告了.这次的题目是codevs 1035 火车停留. 题目大意就是给m个火车的到达时间.停留时间和车载货物的价值,车站有n个车道,而火车停留一次车站就会从车载货物价值中获得1%的利润 ...
随机推荐
- R语言--输入输出
基本输入输出 输入: readline, edit, fix 输出: print, cat 输出重定向 sink #基本输入输出 x=readline('请输入:') #读取输入,一行为一个字符串 x ...
- 一波三折Miz702终于能显示桌面上网啦
先上两张图,总结之后再说啦---
- Qt控件使用汇总
QTableWidget: //tab居中显示 QTabWidget::tab-bar { alignment: center; } //tab边框样式,边框颜色,前景色 QTabBar::tab { ...
- Android Studio Xposed模块编写(一)
1.环境说明 本文主要参考https://my.oschina.net/wisedream/blog/471292?fromerr=rNPFQidG的内容,自己实现了一遍,侵权请告知 已经安装xpos ...
- 【分享】熟练的Java程序员应该掌握哪些技术?
Java程序员应该掌握哪些能力才能算是脱离菜鸟达到熟练的程度? 1.语法:Java程序员必须比较熟悉语法,在写代码的时候IDE的编辑器对某一行报错应该能够根据报错信息 知道是什么样的语法错误并且知道任 ...
- 利用Junit实现eclipse单元测试
在eclipse中使用Junit进行单元测试 今天学会了用Junit在eclipse中进行单元测试,代码的测试工作,在整个软件开发中占有总要的地位,无论是代码开发阶段,还是代码维护阶段.另外边开发边测 ...
- 这可能是最详细的Python文件操作
删除 # ==================删除==================# 只能删除文件,若为目录则报错# 若文件正在使用,Windows下会直接报错,Linux下会在目录表中删除记录, ...
- IT简历
对很多IT毕业生来说,写简历投简历是必不可少的.一个好的简历已是面试成功的一半. 简历的目的是为了引人注意,争取让HR主动联系你去面试,不可避免的在简历中掺杂着一些水分,但是能争取到面试机会,再与HR ...
- highcharts多个Y轴
http://blog.sina.com.cn/s/blog_6a53599101019qax.html 多个Y轴的实现方法在于把yAxis设置成一个数组,里面的一个对象代表一条Y轴,利用opposi ...
- PHP学习 文件访问和写入
<?php $path = $_SERVER['PHP_SELF']; //PHP_SELF:当前执行脚本的文件名,与 document root 有关 echo basename($path) ...