暴力枚举异或操作是会TLE的。按二进制每位的权重拆开,每位上用1出现的数量乘以0出现的数量,再乘以相对应的权, 这其实也就是异或操作中得到1的结果,将它们累加求和即可,结果比较大,用long long储存。
// Problem#: 4423
// Submission#: 3751511
// The source code is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License
// URI: http://creativecommons.org/licenses/by-nc-sa/3.0/
// All Copyright reserved by Informatic Lab of Sun Yat-sen University
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int freq[20];
int main()
{
int test, n, i, j, data;
long long sum;
scanf("%d", &test);
while (test--)
{
memset(freq, 0, sizeof(freq));
scanf("%d", &n);
for (i = 0; i < n; i++)
{
scanf("%d", &data);
for (j = 0; data != 0; j++)
{
if (data & 1)
freq[j]++;
data >>= 1;
}
}
sum = 0;
for (i = 0; i < 20; i++)
sum += (long long)freq[i] * (n - freq[i]) << i;
printf("%lld\n", sum);
}
}