异或后最大lowerbit
https://ac.nowcoder.com/acm/contest/3003/I
题意:给n个地点,每个地点有一个值a,边值花费等于lowerbit(ai异或aj),要使n个地点联通,问最小花费。
解法:要使lowerbit最小考虑最小进制满足存在vi = 1 和 vj = 0 交叉连边 , 注意重复值为0直接去掉,去重后有num个.
答案为(1<<k)* (num-1) , 如果找不到这样的进制就说明点值全都一样,答案为0.
#include <bits/stdc++.h> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <iostream> #include <string> #include <stdio.h> #include <queue> #include <stack> #include <map> #include <set> #include <string.h> #include <vector> #define me(x , y) memset(x , y , sizeof(x)) #define SC scanf #define rep(i , j , n) for(int i = j ; i < n ; i ++) #define red(i , n , j) for(int i = n-1 ; i >= j ; i--) #define INF 0x3f3f3f3f #define mod 1000000007 #define PI acos(-1) using namespace std; typedef long long ll ; int a[200009]; ll ans ; int main() { int n ; SC("%d" , &n); rep(i , 0 , n){SC("%d" , &a[i]);} sort(a , a+n); int num = 0 ; int va = (1<<31)-1 , vo = 0; red(i , n , 0) num += (a[i] != a[i+1]); rep(i , 0 , n) va &= a[i] , vo |= a[i];//分别统计0在哪些位置出现和1在哪些位置出现。 va ^= vo ; rep(i , 0 , 31){ int cur = (1 << i); if(cur & va){//可能找不到这样的某进制既存在0又存在1.比如所有数字相同 ans = 1ll * cur * (num - 1); break ; } } cout << ans << endl; return 0; }