https://codeforces.com/contest/1420/problem/B
思路:位运算嘛..刚前天做了一道类似的题。考虑最高位的贪心.为什么呢?
把数字按照二进制位去思考。
ai & aj≥ai⊕aj
比如
1 1 0
0 0 1
把这两个数进行题目的操作发现,&的操作会让最高位变成0,而异或会变成1,使得不满足题目的统计条件。
再比如
1 __ __
1 __ ___
每个位置1和0两个情况枚举每个情况会发现只有这种情况能满足条件。所以也就说找最高位同为1的数的对数。用一个siz[i]统计最高位都为1的个数,里面每一对都能满足,一个块里的个数和siz[i]的个数有关。
#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<cstdio>
#include<algorithm>
#define debug(a) cout<<#a<<"="<<a<<endl;
using namespace std;
const int maxn=1e5+100;
typedef long long LL;
LL a[maxn],d[40];
bool vis[maxn];
int main(void)
{
cin.tie(0);std::ios::sync_with_stdio(false);
LL t;cin>>t;
while(t--)
{
LL n;cin>>n;
for(LL i=1;i<=n;i++) cin>>a[i],vis[i]=0;
for(LL i=0;i<=40;i++) d[i]=0;
for(LL i=32;i>=1;i--)
{
for(LL j=1;j<=n;j++)
{
if(a[j]&(1<<(i-1))&&!vis[j]) vis[j]=1,d[i]++;
}
}
LL sum=0;
for(LL i=1;i<=32;i++) if(d[i]) sum+=(d[i]*(d[i]-1))/2;
cout<<sum<<endl;
}
return 0;
}