#位运算#CF959E Mahmoud and Ehab and the xor-MST

题目

(n)个点的完全图标号为([0,n-1]),(i)(j)连边权值为(i: xor:j),求MST的值


分析

考虑MST有两种解法一种是Prim一种是Kruskal,Prim应该更好理解。
既然是一个完全图,那么每次新加入一个点,只要找到与它连边的边权最小就可以了
所以题目就转换成每次找到一个(j<i),最小化(i: xor : j)
那尽量让(j)的高位与(i)的高位一致,只改变最后一位即可,
由于异或的运算相同即零不同即一,既然要让(j<i),那么让(j=i: xor : lowbit(i))才是最优的,
因为若边权(<lowbit(i)),那么(j>i),若边权(>lowbit(i)),为何不令边权(=lowbit(i))
所以题目就转换成(sum_{i=1}^{n-1} lowbit(i))
这个(O(log_2n))求就可以了
考虑哪些数对(2^k)有贡献,那就是(2^k)的倍数且非(2^{k+1})的倍数即可,那就是

[lfloorfrac{n}{2^k} floor-lfloorfrac{n}{2^{k+1}} floor=lceilfrac{n}{2^{k+1}} ceil ]


代码

#include <cstdio>
#define rr register
using namespace std;
typedef long long lll; lll ans,n;
signed main(){
	scanf("%lld",&n); --n; 
	for (rr lll two=1;n;n>>=1)
	    ans+=((n+1)>>1)*two,two<<=1;
	return !printf("%lld",ans);
}
原文地址:https://www.cnblogs.com/Spare-No-Effort/p/13921114.html