异或后最大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;
}

 

posted @ 2020-02-07 01:43  无名菜鸟1  阅读(340)  评论(0编辑  收藏  举报