题目:
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3870
题意:
给出n个数,每次选出2个数,问一共有多少种选法使得两数异或后的值大于两个数的最大值。
思路:
对于一个数x,x的最高位0改为1时,且0前的数不变,则x比原来要大。
AC.
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn = 1e5+5;
int a[maxn], bit[35];
void deal(int n)
{
int x = 31;
while(x >= 0) {
if(n & (1<<x)) {
bit[x] ++;
return;
}
x--;
}
return;
}
int main()
{
//freopen("in", "r", stdin);
int T;
scanf("%d", &T);
while(T--) {
int n;
scanf("%d", &n);
memset(bit, 0, sizeof(bit));
for(int i = 0; i < n; ++i) {
scanf("%d", &a[i]);
deal(a[i]);
}
int ans = 0;
for(int i = 0; i < n; ++i) {
int x = 31;
while(x >= 0) {
if(a[i] & (1<<x)) break;
x--;
}
while(x >= 0) {
if(!(a[i] & (1<<x))) ans+=bit[x];
x--;
}
}
printf("%d\n", ans);
}
return 0;
}