UOJ176 新年的繁荣
Boruvka生成树算法
\(Boruvka\)算法就是先把每个点看作一个联通块,然后不断在联通块之间找最优的边进行合并。因为每次联通块的数量最少缩小一半。所以合并次数是\(log\)的
先把所有的点权挂到\(trie\)树上。然后对于每个联通块进行合并的时候。对于联通块中的每个点都去\(trie\)上搜索他能找到的最优秀的边。也就是说如果当前位置是\(1\)那么就搜索1子树,否则的话既要搜0子树,也要搜1子树。这样1子树是一定要搜的。所以把0子树变为1子树和0子树合并起来的结果。然后就可以搜索了。
还有一个问题就是。如果当前子树中的所有点都已经在这个联通块里了怎么办。所以统计出每棵子树中联通块编号的最大值和最小值。然后就可以知道当前子树中是不是还有不属于这个联通块里的点了。合并联通块之后再把每个点合并的联通块里的点所属的联通块修改一下就行了。
复杂度\(O((n+2^m)mlogn)\)
更优秀的做法
上面的做法代码长且思路复杂。有一种更好的做法。
先把所有权值相同的点连一条边。这样肯定会比较优秀。
然后考虑枚举最终答案中\(w[u]\&w[v]\)的值p。
因为\(x\&w[u] \leq w[u]\),倒着枚举p,然后找到一个点u使得\(w[u]\&p=p\)。然后从其他的等于满足\(w[v]\&p=p\)的点\(v\)中找一个与\(u\)不在同一个联通块里的点。将这两个点之间连边。贡献为\(p\)。
万一\(w[u]\&w[v]\)比\(p\)大呢。可以证明这是不可能的。因为p是倒着枚举的,如果\(w[u]\&w[v]>p\)那么肯定之前就连过边了。不会再连一次。
复杂度\(O(2^mm\alpha(n))\)
代码
/*
* @Author: wxyww
* @Date: 2019-01-21 15:46:58
* @Last Modified time: 2019-01-21 15:53:01
*/
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cmath>
#include<ctime>
#include<bitset>
using namespace std;
typedef long long ll;
const int N = 1000000 +10;
ll read() {
ll x=0,f=1;char c=getchar();
while(c<'0'||c>'9') {
if(c=='-') f=-1;
c=getchar();
}
while(c>='0'&&c<='9') {
x=x*10+c-'0';
c=getchar();
}
return x*f;
}
int p[N],fa[N];
ll ans;
int find(int x) {
return fa[x] == x ? x :fa[x] = find(fa[x]);
}
void uni(int x,int y) {
x = find(x),y = find(y);
if(rand() & 1) fa[x] = y;
else fa[y] = x;
}
int main() {
srand(time(0));
int n = read(),m = read();
for(int i = 1;i <= n;++i) {
int x = read();
if(p[x]) ans += x;
p[x] = x;
}
int k = (1 << m);
for(int i = 1;i <= k;++i) fa[i] = i;
for(int i = (1 << m) - 1;i;--i) {
for(int j = 0;j < m && !p[i];++j) p[i] = p[i | (1 << j)];
int u = p[i];
if(!u) continue;
for(int j = 0;j < m;++j) {
int v = p[i | (1 << j)];
if(!v) continue;
if(find(v) != find(u)) {
ans += i;
uni(u,v);
}
}
}
cout<<ans;
return 0;
}
UOJ176 新年的繁荣的更多相关文章
- C. 新年的繁荣
题解: 用最小生成树的Boruvka算法 即每次找到每个点不在它联通块的边内的最大值 然后进行log次这个过程 然后找这个的话我们可以用trie树在2^m的时间内完成建树(如果是1要合并到0上)
- UOJ 176 新年的繁荣
挺妙的解法. 发现边权很小,我们可以考虑从大到小枚举边权来进行$kruskal$算法,这样子对于每一个边权$i$,我们只要枚举$0 \leq j < m$,找到一个点使它的点权为$i | 2^j ...
- CF888G Xor-MST[最小生成树+01trie]
前注:关于这题,本人的解法暂时没有成功通过此题,原因是被卡常了.可能需要等待某种机缘来请人调试. 类似uoj的一道题(新年的繁荣),不过是一个有些简单的版本. 因为是完全图,有没有办法明显优化建边,所 ...
- 金牛来到,福气来到——TcaplusDB新年放送
光阴似箭,2020转瞬间成为历史,牛年的钟声即将敲响,在此,TcaplusDB祝大家新的一年万事如意,牛年带给我们的福气,一定能让我们心想事成! 饮水思源,回顾过去的一年,我们深知,TcaplusDB ...
- 新年抢红包效果(New Year Red Packet)
新年抢红包效果(New Year Red Packet) 晓娜的文章(微信公众号:migufe) 2016即将过去,我们将迎来新的一年2017,这里小编提前祝大家新年快乐!万事如意!那我们新年最开心的 ...
- 【UOJ#67】新年的毒瘤 Tarjan 割点
#67. 新年的毒瘤 UOJ直接黏贴会炸... 还是戳这里吧: http://uoj.ac/problem/67#tab-statement Solution 看到这题的标签就进来看了一眼. 想 ...
- 喜迎2015年新年:坦克大战(Robocode)游戏编程比赛图文总结
2015春节前,葡萄城的软件工程师以特有的方式来迎接新年——2015新年编程邀请赛. 邀请赛的初衷,是和大家一起,寻找编程最初的单纯的快乐. 在代码的世界里,添加动力,继续远航. ...
- uoj 67 新年的毒瘤 割点
题目链接: 题目 #67. 新年的毒瘤 问题描述 辞旧迎新之际,喜羊羊正在打理羊村的绿化带,然后他发现了一棵长着毒瘤的树. 这个长着毒瘤的树可以用 nn 个结点 mm 条无向边的无向图表示.这个图中有 ...
- CT 来值班,让您安心过新年!
春节,盼了整整一年的节日,我们一定要抛开工作,狠狠的开心,狠狠的幸福,但是作为苦逼的运维,你们真的能完全抛开工作(对网站不闻不问)吗?OneAPM CT 24 小时监控您的网站,让您无忧无虑过新年. ...
随机推荐
- String类内存空间详解
java.lang.String类内存问题详解 字符串理解的难点在于其在堆内存空间上的特殊性,字符串String对象在堆内存上有两种空间: 字符串池(String pool):特殊的堆内存,专门存放S ...
- python爬虫之线程池和进程池
一.需求 最近准备爬取某电商网站的数据,先不考虑代理.分布式,先说效率问题(当然你要是请求的太快就会被封掉,亲测,400个请求过去,服务器直接拒绝连接,心碎),步入正题.一般情况下小白的我们第一个想到 ...
- Ubuntu install flash
Software&Updates - Other Software - Canonical Parners sudo apt install adobe-flashplugin
- Vue入门基础
前面的话 Vue中文文档写得很好,界面清爽,内容翔实.但文档毕竟不是教程,文档一上来出现了大量的新概念,对于新手而言,并不友好.个人还是比较喜欢类似于<JS高级程序设计>的风格,从浅入深, ...
- How to write to an event log by using Visual C#
using System; using System.Diagnostics; namespace WriteToAnEventLog_csharp { /// Summary description ...
- codeforces498C
Array and Operations CodeForces - 498C You have written on a piece of paper an array of n positive i ...
- servlet篇 之 生命周期
二:Servlet的生命周期 背景知识: servlet是单例,在web项目运行期间,一个servlet只会创建一个对象[tomcat帮我们实例 化][尽量不要在servlet中定义成员变量].因为w ...
- 如何创建djiago项目和djiago连接数据库
介绍 主要介绍在python中如何使用pycharm创建djiago项目以及如何将djiago项目和mysal数据库连接起来 创建djiago项目 1.使用pycharm创建djiao项目 点击pyc ...
- Spring 使用介绍(十三)—— Bean的生命周期
一.概述 Spring Bean的完整生命周期从创建Spring容器开始,直到最终Spring容器销毁Bean,生命周期时序图如下: 二.生命周期接口分类 Bean的生命周期经历了多个接口方法的调用, ...
- 解决Docker容器中不能用vim编辑文件
更新来源: apt-get update 安装vim apt-get install -y vim 参考链接:https://blog.csdn.net/wangxinxinsj/article/de ...