题目描述
输入描述:
输出描述:
输出一行,一个整数表示答案。
示例1
说明
思路
对于此题来说,抛去所有附加条件不管,是一个MST问题。
然鹅对于这种数据范围,即使处理了重复的点再去建边跑KRUSKAL也是不科学的(将信将疑
于是乎我们来思考别的解法。
首先,毋庸置疑,肯定是去重,因为异或相同为0嘛,没有花费当然要连咯。
其次,对于最小花费,只要全为奇数或偶数肯定是0嘛。
说到这里肯定有很多小伙伴喷我,然鹅原题面就是这样的,后来经过和出题人一顿BBOX,他才把题面改了。。。
从此时起,一切就变了。lowbit的定义变成了最低非0位(一开始写的是最低位),所以我们开始找最低的那个1在哪。
关于这个最低的非0位,需要满足一个条件,就是在这一位上,其他所有点的权值转化为二进制后的这一位,得异或出来一个1。
怎样才能异或出来一个1呢,相信大家大一的时候上大计基课都学过异或的口诀,“相同为0,不同为1”,所以只要所有的点权值转化为二进制后,这一位有0又有1就好啦。
如何找到这一位呢,我们从最基础的角度思考(因为我只会点基础),利用&1的操作就可以辣,所以我们只要当找不到一个位上有0又有1时(gay圈现状),就把权值右移1位,直到找到某一位上有0又有1为止。
如果还有不太清楚的同学可以试试去掉注释,输出过程看看,手动写写就知道了。
CODE
1 #include <bits/stdc++.h> 2 #define dbg(x) cout << #x << "=" << x << endl 3 4 using namespace std; 5 typedef long long LL; 6 const int kmaxn = 3e5 + 7; 7 8 int a[kmaxn]; 9 set <int> s[37]; 10 int f[35][2]; 11 12 template<class T>inline void read(T &res) 13 { 14 char c;T flag=1; 15 while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;res=c-'0'; 16 while((c=getchar())>='0'&&c<='9')res=res*10+c-'0';res*=flag; 17 } 18 19 namespace _buff { 20 const size_t BUFF = 1 << 19; 21 char ibuf[BUFF], *ib = ibuf, *ie = ibuf; 22 char getc() { 23 if (ib == ie) { 24 ib = ibuf; 25 ie = ibuf + fread(ibuf, 1, BUFF, stdin); 26 } 27 return ib == ie ? -1 : *ib++; 28 } 29 } 30 31 int qread() { 32 using namespace _buff; 33 int ret = 0; 34 bool pos = true; 35 char c = getc(); 36 for (; (c < '0' || c > '9') && c != '-'; c = getc()) { 37 assert(~c); 38 } 39 if (c == '-') { 40 pos = false; 41 c = getc(); 42 } 43 for (; c >= '0' && c <= '9'; c = getc()) { 44 ret = (ret << 3) + (ret << 1) + (c ^ 48); 45 } 46 return pos ? ret : -ret; 47 } 48 49 int main() 50 { 51 int n; 52 read(n); 53 for(int i = 1; i <= n; ++i) { 54 int x; 55 read(x); 56 s[0].insert(x); 57 f[0][x&1]++; 58 } 59 /* 60 printf("f[0][0]:%d f[0][1]:%d ",f[0][0],f[0][1]); 61 int d = s[0].size(); 62 for(set<int> ::const_iterator p = s[0].cbegin(); p != s[0].cend(); ++p) { 63 cout << *p <<endl; 64 } 65 */ 66 LL ans = 0; 67 for(int i = 0; i <= 30; ++i) { 68 if(f[i][0] && f[i][1]) { 69 ans = (s[i].size()-1) * (1 << i); 70 break; 71 } 72 for(auto it : s[i]) { 73 s[i+1].insert(it >> 1); 74 f[i+1][(it>>1)&1]++; 75 } 76 /* 77 printf("f[%d][0]:%d f[%d][1]:%d ",i,f[i][0],i,f[i][1]); 78 int d1 = s[i].size(); 79 for(set<int> ::const_iterator p = s[i].cbegin(); p != s[i].cend(); ++p) { 80 cout << *p <<endl; 81 } 82 */ 83 } 84 cout << ans << endl; 85 return 0; 86 }