题意就是有n个数,如果满足a^b > MAX(a, b),就算一种组合,问n个数之间这样的组合有多少个;
可以发现,如果要让一个数增大,只要该数化为二进制后的出现0的位置跟1异或就会变大,
同时需要满足另一个数的最高位为该数出现0位置的位数,
如10可以跟1异或变为11 ,100可以跟10、11、1异或分别变为110,111,101,而101只能跟两位的进行异或,
因为它的0出现的位置为第二位,最后求和就行了。
在输入的时候用 a数组存储输入的数据,顺便cnt[i]代表a数组都转换成二进制数的位数(因为第一位必定为1);
然后开始遍历数组a,转化成二进制 从第一位开始遍历是0的数,碰到是0的位数i 就ans*=cnt[i];
#include<iostream>
#include<string.h>
#define ll long long
using namespace std;
int trans1(int x)
{
int s[100],i=0;
while(x)
{
s[++i]=x&1;
x>>=1;
}
if(s[i])
return i;
else return 0;
}
int main()
{
int t,a[100005],n,i,cnt[100];
cin>>t;
while(t--)
{
cin>>n;
memset(cnt,0,sizeof(cnt));
int ans=0;
for(i=0;i<n;i++)
{
cin>>a[i];
int t=trans1(a[i]);
if(t)
cnt[t]++;
}
for(i=0;i<n;i++)
{
int s[100],k=0;
int x=a[i];
while(x)
{
s[++k]=x&1;
x>>=1;
}
for(int j=k;j>0;j--)
if(s[j]==0)
ans+=cnt[j];
}
cout<<ans<<endl;
}
return 0;
}