Codeforces Gym 101484 K Counting Good Teams

来源:互联网 发布:数据表格共享平台 编辑:程序博客网 时间:2024/05/06 19:15

原题链接:

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;}
原创粉丝点击