For an upcoming programming contest, Edward, the headmaster of Marjar University, is forming a two-man team from N students of his university.
Edward knows the skill level of each student. He has found that if two students with skill level A and B form a team, the skill level of the team will be A ⊕ B, where ⊕ means bitwise exclusive or. A team will play well if and only if the skill level of the team is greater than the skill level of each team member (i.e. A ⊕ B > max{A, B}).
Edward wants to form a team that will play well in the contest. Please tell him the possible number of such teams. Two teams are considered different if there is at least one different team member.
Input
There are multiple test cases. The first line of input contains an integer T indicating the number of test cases. For each test case:
The first line contains an integer N (2 <= N <= 100000), which indicates the number of student. The next line contains N positive integers separated by spaces. The ith integer denotes the skill level of ith student. Every integer will not exceed 109.
Output
For each case, print the answer in one line.
Sample Input
2
3
1 2 3
5
1 2 3 4 5
Sample Output
1
6
题目意思,有n个人,每个人有能力值,随便找两个人组队,如果两个人的能力值进行异或运算的结果>max(a,b)说明这队满足条件,求多少队能满足这样的条件。
分析:对一个数 a 10101来说想让别的数和它进行异或运算后它变大,也就是他的零位是在另一个数的位是1,而且这个1在另一位的位就是最高位。10, 1000都能满足这个条件,如果是1100或者110,在a中的0之前有相同的1,1和1异或变成0了,就变小了。所以看变小还是变大,别的数最高位在a中是1还是0。
#include <bits/stdc++.h>
#define ll long long
using namespace std;
int a[111]; //记录每个2进制长度的有几个,a[n]代表长度为n的有几个。也就是最高位。
int ans[111111];
int main()
{
int t;
ios::sync_with_stdio(false);
cin >> t;
while(t--)
{
int n, k, x;
ll sum = 0;
cin >> n;
memset(a, 0, sizeof(a));
for(int i = 1; i <= n; i++)
{
cin >> x;
ans[i] = x;
k = 0;
while(x)
{
k++;
x/=2;
}
a[k]++; //预处理,直接记录好。
}
for(int i = 1; i <= n; i++)
{
x = ans[i];
k = 0;
while(x)
{
k++;
if(x%2==0) //遍历的过程,如果第k位是0,长度为k的数和它异或,它一定变大。
sum+=a[k];
x/=2;
}
}
cout << sum << endl;
}
return 0;
}