链接
题目描述
给出 n个数字的一个序列A,你可以将他们分为若干组,每一组的权值是里面数字的异或和,求使得所有组权值和最小。
思路
我贪心,贪了个寂寞(高位相同异或
其实就把所有数异或起来就好了
因为异或其实就是加法不进位
比加法进位要优,所以全异或起来就完事了
代码
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define ll long long
using namespace std;
ll t, n, a[100005], ans, tot, sum, pl;
bool cmp(int x, int y)
{
return x > y;
}
int main()
{
scanf("%lld", &n);
for(int i = 1; i <= n; ++i)
scanf("%lld", &a[i]);
sort(a + 1, a + n + 1, cmp);
t = n;
for(int i = 31; i >= 0; --i) {
pl = 0;
int tt = t;
sum = 0;
tot = 0;
for(int j = 1; j <= tt; ++j)
{
if(a[j] & (1 << i)) {
tot++;
sum ^= a[j];
a[j] = 0;
pl = j;
t--;
}
if(tot == 2) {
a[pl] = sum;
sum = 0;
tot = 0;
t++;
}
}
if(tot == 1) a[pl] = sum, t++;
sort(a + 1, a + tt + 1, cmp);
}
for(int i = 1; i <= t; ++i)
ans += a[i];
printf("%lld", ans);
return 0;
}