您的位置:首页 > 大数据 > 人工智能

CodeChef:Good Pairs(dp & 二进制)

2017-08-15 23:00 323 查看
You are given N integers: A1, A2, ..., AN.
You need to count the number of pairs of indices (i, j) such that 1 ≤ i < j ≤ N and Ai | Aj ≤
max(Ai, Aj).

Note: Ai | Aj refers to bitwise
OR.


Input

The first line of the input contains an integer T, denoting the number of test cases. The description of each testcase follows.
The first line of each testcase contains a single integer: N
The second line of each testcase contains N integers: A1, A2,
..., AN


Output

For each test case, output a single line containing the answer for that test case.


Constraints

1 ≤ T ≤ 20
1 ≤ N ≤ 106
0 ≤ Ai ≤ 106
1 ≤ Sum of N over all test cases ≤ 106

题意:給N个数字,问有多少对数满足a[i]|a[j] <= max(a[i],a[j]),i<j。

思路:首先a[i]|a[j] >= max(a[i],a[j]),于是题目变成求a[i]|a[j] == max(a[i],a[j]),若a[i]<=a[j],那么a[i]|a[j] == a[j],即a[i]为a[j]的二进制子集,那么求出每个数在这N个数里有多少个它的子集即可,sum over subsets dp复杂度O(N*2^N),N<21。

# include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 1e6;
LL num[maxn+3], num2[maxn+3];
int main()
{
int t, n, m;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
memset(num, 0, sizeof(num));
memset(num2, 0, sizeof(num));
for(int i=0; i<n; ++i)
{
scanf("%d",&m);
++num[m];
++num2[m];
}
for(int i=0; i<21; ++i)
for(int j=1; j<=maxn; ++j)
if(j&(1<<i))
num[j] += num[j^(1<<i)];
LL ans = 0;
for(int i=0; i<=maxn; ++i)
{
if(num[i])
{
ans += num2[i]*(num2[i]-1)/2;
ans += (num[i]-num2[i])*num2[i];
}
}
printf("%lld\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: