//题意:从一堆数字中任选两个数字,使其异或后的值大于这两个数字的任意一个 求这样的数字有多少对
//方法: 如果要两个数字异或后的值大于任意一个
// 只需要大的那个元素的最高位大于小的那个元素的最高位且
// 小的元素的最高位对应的大的元素的该位上的数字为0即可
// 利用数组bits[i](二进制最高位为i的数字有多少个)进行累加即可
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <algorithm>
#include <iostream>
using namespace std;
int bits[35];
int ss[100005];
int cnt[100005];
long long ans;
void find_(int x)
{
for(int i = cnt[x]; i>= 0; i--)
{
if( !((1 << i) & ss[x]) ){
ans += bits[i];
}
}
}
int cal(int x)
{
int i = 31;
while(i >= 0)
{
if(x & (1 << i)){
bits[i]++;
return i;
}
else i--;
}
}
int main()
{
int t, n, temp;
scanf("%d", &t);
while(t--)
{
scanf("%d", &n);
memset(bits, 0, sizeof bits);
for(int i = 0; i < n; i++)
{
scanf("%d", &ss[i]);
cnt[i] = cal(ss[i]);
}
ans = 0;
for(int i = 0; i < n; i++)
find_(i);
printf("%d\n", ans);
}
return 0;
}
ZOJ 3870(数学)
最新推荐文章于 2020-10-14 22:20:53 发布