数据多,而且数据大,稍不小心就会TLE或者是WA。如果是单纯地两两异或,就算用了^异或这个位操作符,由于O(n2)的时间复杂度,结果仍然会超时。一个优化是统计每个数的二进制不同位上的01信息,将所有的数统计完毕后,在每个的位上,将0出现的次数乘上1出现的次数,再乘上当前位的权数(即2的0、1、2……次方),然后相加就是答案,这样只需要O(n)的时间复杂度。
需要注意的是数据量最大是1000000,开数组不太现实,最好是读入一个数处理一个数;最大的数据是1000000,转换成二进制后有20位,要开一个20位的数组来统计不同位置上0(或者1)的次数,并且相乘时要转换成long long类型以防丢失数据。
Run Time: 0.29sec
Run Memory: 304KB
Code length: 673Bytes
Submit Time: 2011-12-15 14:39:12
// Problem#: 4423
// Submission#: 1079897
// 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 <cstdio>
using namespace std;
int main()
{
int T, N;
int i, j;
int data;
long long sum;
scanf( "%d", &T );
while ( T-- ) {
int freq[ 20 ] = { };
scanf( "%d", &N );
for ( i = 0; i < N; i++ ) {
scanf( "%d", &data );
for ( j = 0; data != 0; j++ ) {
if ( data % 2 == 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 );
}
return 0;
}