【CF888G】Xor-MST
也不是很知道为什么这道题要和某\(B\)姓算法扯上关系
首先有一个非常显然基于那个\(B\)姓算法的做法,每次启发式合并\(trie\)即可,复杂度是\(O(n\ logn\ loga_i)\)
这个做法太无脑了,考虑一个高端的做法,只需要\(kruskal\)的思想就够了
我们还是先建出一棵\(trie\),我们考虑我们得到了某个节点左右两个儿子的\(mst\),之后如何合并出整个子树的\(mst\)
看起来就是在扯淡,\(mst\)这个东西显然不是能随随便便合并的东西
但是我们考虑一下这个题的特殊性质,我们左右两个子树的\(mst\)内的边都是小于过这个节点的边的,因为过这个节点的边在这一个比较高的二进制位上异或起来是\(1\)
所以我们连过这个节点的边无论怎么连都不会小于之前两个\(mst\)里的边,所以原来\(mst\)里的边在合并后的新\(mst\)里都是存在的,所以我们只需要在左右两个儿子里找一个最小的异或值加入答案就可以了
找两个\(trie\)对应的最小的异或值,我们显然可以直接暴力比对两个\(trie\),这样下来每个点最多会被暴力到\(loga_i\)次,所以总复杂度是\(O(nlog^2a_i)\)
先染实际上根本跑不满,感觉并没有比一个\(log\)慢多少当然也有可能是我分析错了
代码
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define re register
#define LL long long
#define min std::min
inline int read() {
char c=getchar();
int x=0;
while(c<'0'||c>'9') c=getchar();
while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-48,c=getchar();
return x;
}
const int maxn=2e5+5;
const LL inf=1e15;
int n,a[maxn],son[maxn*31][2],bit[31],cnt;
inline void ins(int x) {
memset(bit,0,sizeof(bit));
for(re int i=0; i<30; i++)
bit[i]=(x&(1<<i))>0;
int now=1;
for(re int i=29; i>=0; --i) {
if(!son[now][bit[i]]) son[now][bit[i]]=++cnt;
now=son[now][bit[i]];
}
}
LL chk(int x,int y,int w) {
if(!x||!y) return 0;
LL t=inf;
if(son[x][0]&&son[y][0]) t=min(t,chk(son[x][0],son[y][0],w-1));
if(son[x][1]&&son[y][1]) t=min(t,chk(son[x][1],son[y][1],w-1));
if(t==inf) {
if(son[x][1]&&son[y][0]) t=min(t,chk(son[x][1],son[y][0],w-1)),t+=(1<<w);
if(son[x][0]&&son[y][1]) t=min(t,chk(son[x][0],son[y][1],w-1)),t+=(1<<w);
if(t==inf) t=0;
}
return t;
}
LL dfs(int x,int w) {
if(!x||w<0) return 0;
if(son[x][0]&&son[x][1])
return (1<<w)+chk(son[x][0],son[x][1],w-1)+dfs(son[x][0],w-1)+dfs(son[x][1],w-1);
return dfs(son[x][0],w-1)+dfs(son[x][1],w-1);
}
int main() {
n=read();
cnt=1;
for(re int i=1; i<=n; i++) a[i]=read();
std::sort(a+1,a+n+1);n=std::unique(a+1,a+n+1)-a-1;
for(re int i=1; i<=n; i++) ins(a[i]);
printf("%lld\n",dfs(1,29));
return 0;
}
【CF888G】Xor-MST的更多相关文章
- 【BZOJ2337】Xor和路径(高斯消元)
[BZOJ2337]Xor和路径(高斯消元) 题面 BZOJ 题解 我应该多学点套路: 对于xor之类的位运算,要想到每一位拆开算贡献 所以,对于每一位拆开来看 好了,既然是按位来算 我们就只需要计算 ...
- 【AtCoder3611】Tree MST(点分治,最小生成树)
[AtCoder3611]Tree MST(点分治,最小生成树) 题面 AtCoder 洛谷 给定一棵\(n\)个节点的树,现有有一张完全图,两点\(x,y\)之间的边长为\(w[x]+w[y]+di ...
- 【AtCoder2134】ZigZag MST(最小生成树)
[AtCoder2134]ZigZag MST(最小生成树) 题面 洛谷 AtCoder 题解 这题就很鬼畜.. 既然每次连边,连出来的边的权值是递增的,所以拿个线段树xjb维护一下就可以做了.那么意 ...
- 【CF888G】Xor-MST Trie树(模拟最小生成树)
[CF888G]Xor-MST 题意:给你一张n个点的完全图,每个点有一个权值ai,i到j的边权使ai^aj,求这张图的最小生成树. n<=200000,ai<2^30 题解:学到了求最小 ...
- 【CF888G】Xor-MST(最小生成树,Trie树)
[CF888G]Xor-MST(最小生成树,Trie树) 题面 CF 洛谷 题解 利用\(Kruskal\)或者\(Prim\)算法都很不好计算. 然而我们还有一个叫啥来着?\(B\)啥啥的算法,就叫 ...
- 【BZOJ2115】Xor(线性基)
[BZOJ2115]Xor(线性基) 题面 BZOJ Description Input 第一行包含两个整数N和 M, 表示该无向图中点的数目与边的数目. 接下来M 行描述 M 条边,每行三个整数Si ...
- 【BZOJ1937】[Shoi2004]Mst 最小生成树 KM算法(线性规划)
[BZOJ1937][Shoi2004]Mst 最小生成树 Description Input 第一行为N.M,其中 表示顶点的数目, 表示边的数目.顶点的编号为1.2.3.…….N-1.N.接下来的 ...
- 【HDU3949】XOR
[题目大意] 给定一个数组,求这些数组通过异或能得到的数中的第k小是多少. 传送门:http://vjudge.net/problem/HDU-3949 [题解] 首先高斯消元求出线性基,然后将k按照 ...
- BZOJ 2115 【Wc2011】 Xor
Description Input 第一行包含两个整数N和 M, 表示该无向图中点的数目与边的数目. 接下来M 行描述 M 条边,每行三个整数Si,Ti ,Di,表示 Si 与Ti之间存在 一条权值为 ...
- 【BZOJ-2115】Xor 线性基 + DFS
2115: [Wc2011] Xor Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 2142 Solved: 893[Submit][Status] ...
随机推荐
- Apache 环境变量配置
在path 中加入 C:\__S_D_K__\AndroidApache\apache-ant-1.9.14\bin 我的路径在C盘
- TopCoder[SRM587 DIV 1]:ThreeColorability(900)
Problem Statement There is a H times W rectangle divided into unit cells. The rows of cells are ...
- 字符串dp——牛客多校第五场G
比赛的时候脑瘫了没想出来..打多校以来最自闭的一场 显然从s中选择大于m个数组成的数必然比t大,所以只要dp求出从s中选择m个数大于t的方案数 官方题解是反着往前推,想了下反着推的确简单,因为高位的数 ...
- spark-sql性能优化之——动态实现多个列应用同一个函数
在对一个dataframe的多个列实现应用同一个函数时,是否能动态的指定? 例如: 对A,B,C三列实现分组统计 1.初始化spark,构建DF val spark = SparkSession.bu ...
- LightOJ 1245 - Harmonic Number (II)
题目链接:http://www.lightoj.com/volume_showproblem.php?problem=1245 题意:仿照上面那题他想求这么个公式的数.但是递归太慢啦.让你找公式咯. ...
- NPE问题
“防止 NPE,是程序员的基本修养.”NPE(Null Pointer Exception) 参考: https://www.jianshu.com/p/9915f2e34a13
- Dubbo的服务请求失败怎么处理
dubbo启动时默认有重试机制和超时机制. 超时机制的规则是如果在一定的时间内,provider没有返回,则认为本次调用失败, 重试机制在出现调用失败时,会再次调用.如果在配置的调用次数内都失败,则认 ...
- 微信公众号支付出现:“当前页面的URL未注册”
微信公众号H5调起支付时,点击支付按钮出现“当前页面的URL未注册”的提示.解决办法:由于2017年8月1日微信官方把关于支付的信息转移到了商户平台:公众平台微信支付公众号支付授权目录.扫码支付回调U ...
- leetcode-90-子集②
题目描述: 方法一:回溯 class Solution: def subsetsWithDup(self, nums: List[int]) -> List[List[int]]: nums.s ...
- matlab中乘法和点乘以及除法和点除的联系是什么?
一,*和.*的联系和区别. 1,在进行数值运行和数值乘矩阵,这两种没有区别,例如:a*b=a.*b; a*B=a.*B; B*a=B.*a (其中小写字母表示数值,大写字母表示矩阵,下同). 2,在处 ...