标签:zoj
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <cmath> #include <queue> #include <stack> #include <vector> #include <map> #include <set> #include <deque> #include <cctype> #define LL long long #define INF 0x7fffffff using namespace std; int bit[100005][40];//分解成二进制 int num[100005][40];//从后到前记录每一个位中1的个数 int len[100005]; //分解的二进制数的长度 int a[100005]; void fun(int x){ int j = 0; while(a[x]){ bit[x][j++] = a[x] % 2; a[x] /= 2; } len[x] = j; } int main() { int t; scanf("%d",&t); while(t--){ int n; scanf("%d",&n); memset(num,0,sizeof(num)); memset(len,0,sizeof(len)); for(int i = 0;i < n;i++){ scanf("%d",&a[i]); } sort(a,a+n); //按照从小到大排序,如 a < b;如果b在a的最高位所对应的二进制数是0则a异或b肯定大于 //例如:10 111 10 < 111在111在10的最高位的位置是1所以不能配对,但是101可以 long long int ans = 0; for(int i = n-1;i >=0 ;i--){ //从后到前统计每一位总共有多少个1, for(int j = 0;j < 40;j++){ num[i][j] = num[i+1][j]; } fun(i); for(int j = 0;j < len[i];j++){ if(bit[i][j]){ num[i][j]++; } } ans += n - i - num[i][len[i] - 1]; //当前位置之后的数个个数减去在a[i]的最高位上是1的数的个数就是能配对的个数 } cout << ans << endl; } return 0; }
标签:zoj
原文地址:http://blog.csdn.net/qq_24667639/article/details/45272865