题目传送门
题目描述
在无垠的宇宙中,有 n 个星球,第 i 个星球有权值 。
由于星球之间距离极远,因此想在有限的时间内在星际间旅行,就必须要在星球间建立传送通道。
任意两个星球之间均可以建立传送通道,不过花费并不一样。第 i 个星球与第 j 个星球的之间建立传送通道的花费是 ,其中
为二进制异或,而
为 x 二进制最低位 1 对应的值,例如
。特殊地,
。
牛牛想在这 n 个星球间穿梭,于是――你需要告诉 牛牛,要使这 n 个星球相互可达,需要的花费最少是多少。
输入描述:
第一行,一个正整数 n 。
第二行,n 个非负整数 。
保证 。
输出描述:
输出一行,一个整数表示答案。
输入
2
1 2
输出
1
说明
号点之间建立通道,
题解
- 首先将权值去重(权值相等的点连接代价为 0 ),设去重后有 m 个点,接下来找到最小的二进制位 k ,满足存在
的这个二进制位是 0 且存在
的这个二进制位是 1 ,答案就是
(相当于所有这位是 0 的点与 j 点连边,是 1 的点与 i 点连边)。
- 排序和去重以外时间复杂度
,没有卡
,好像两个
AC-Code
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define
const int maxn = 2e5 + 5;
int a[maxn];
int main() {
ios;
int n; cin >> n; ll ans = 0;
for (int i = 0; i < n; ++i) cin >> a[i];
sort(a, a + n);
int tot = unique(a, a + n) - a; // 去重
int v1 = 0, v0 = 0xffffffff;
for (int i = 0; i < tot; ++i) { // 取所有的每个位置的 0和1
v1 |= a[i];
v0 &= a[i];
}
int k = v1 ^ v0; // 得到既有0又有1的位置
int i = 0;
while (k > 0) { // 如果存在计算,不存在的话代价就是0
int c = 1 << i++;
if (k & c) {
ans = c * (tot - 1);
break;
}
}
cout << ans << endl;
}