题意:两个数异或的结果大于这两个数,求有多少对这样的数。
题记:找出所有数的二进制的左边第一个1的位置。vis[i]记录下1在第i位的数的个数。然后遍历所有数,当这个数的二进制的第i位为0时异或一个左边第一个1的位置在i的数是会变大的。
例如:(二进制表示)
100111异或1xxx和1xxxx都会变大。x取0和1都不会影响结果。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+10;
int vis[100];
int a[N];
int main(){
int T;
cin>>T;
while(T--){
memset(vis,0,sizeof(vis));
ll ans=0;
int n;
cin>>n;
for(int i=0;i<n;i++){
cin>>a[i];
int k=0,x=a[i];
while(x){
k++;
x>>=1;
}
vis[k]++;
}
for(int i=0;i<n;i++){
int x=a[i],k=0;
while(x){
k++;
if(!(x&1))ans+=vis[k];
x>>=1;
}
}
cout<<ans<<endl;
}
return 0;
}