您的位置:首页 > 编程语言 > Go语言

Codeforces Gym 101484 K Counting Good Teams

2017-10-03 14:08 351 查看

原题链接:

http://codeforces.com/gym/101484/problem/K

题意

N个人,任选两个人组队,每个人有一个代表自己能力的二进制数值xi(输入中以十进制数的形式给出),如果两个人的二进制表示中都至少有一位,自己是1,对方是0,则这两个人可以组成一个good team,题目问有多少组good team。数据范围(N <= 1e5, xi < 2 ^ M, M <= 21)

分析:

按位统计

由题意显然可得,一个good team的两个成员i, j,(xi | xj) > xi && (xi | xj) > xj ,我们考虑相反的情况,即 (xi | xj) == max(xi, xj)。所以,我们只要枚举每个数xi,统计有多少满足(xj <= xi && xj | xi == xi)的数。

代码:

#include <bits/stdc++.h>
using namespace std;

const int maxn = 2100000 + 50;
long long cnt[maxn], dn[maxn];

int main()
{
int n, m;
scanf("%d %d", &n, &m);
for (int i = 0; i < n; ++i)
{
int x;
scanf("%d", &x);
cnt[x]++;
dn[x]++;
}
for (int i = 0; i < m; ++i)
{
for (int j = 0; j < (1 << m); ++j)
{
if ((j & (1 << i)) == 0) continue;
dn[j] += dn[j ^ (1 << i)];
}
}
long long ans = (long long)(n - 1) * (long long)n / 2LL;
for (int i = 0; i < (1 << m); ++i)
{
ans -= cnt[i] * dn[i] - (cnt[i] * (cnt[i] + 1) / 2);
}
cout << ans << endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  codeforces