(3870)ZOJ

来源:互联网 发布:软件项目风险评估报告 编辑:程序博客网 时间:2024/06/09 20:44
#include <bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<string.h>
#include<cstring>
#include<string>
#include<stack>
#include<set>
#include<algorithm>
#include<cmath>
#include<vector>
#include<map>

#define LOCAL
#define ll long long
#define lll unsigned long long
#define MAX 1000009
#define eps 1e-8
#define INF 0x7fffffff
#define mod 1000000007
#define lson l , m, rt<<1
#define rson m+1,r,rt<<1|1
using namespace std;

/*

题意:求数组中任意两个数 如果A亦或B大于max(A,B)的方案数

想法:求出每个数最左边那位的1,然后记录每个位置有多少个这样的1,一求和就可以了。

*/

int a[MAX];
int bit[109];


int main()
{
//#ifdef LOCAL
    //freopen("date.in","r",stdin);
    //freopen("date.out","w",stdout);
//#endif // LOCA
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int n;
        memset(bit,0,sizeof(bit));
        scanf("%d",&n);
        for(int i = 0; i<n; i++)
        {
            scanf("%d",&a[i]);
            for(int j = 31; j>=0; j--)
            {
                if(a[i]&(1<<j))
                {
                    bit[j]++;
                    break;
                }
            }
        }
        ll sum = 0;
        for(int i  =0; i<n; i++)
        {
            if(a[i])
            {
                int L = 31;
                while(1)
                {
                    if(a[i]&(1<<L))break;
                    L--;
                }
                while(L>=0)
                {
                    if(!(a[i]&(1<<L)))
                    {
                        sum+=bit[L];//枚举下面0的位置,0亦或1为1所以增大
                    }
                    L--;
                }
            }
        }
        printf("%lld\n",sum);
    }
//#ifdef LOCAL
 //   cout<< "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC * 1000 << " ms." << endl;
//#endif
    return 0;
}

0 0