B3618 寻找团伙

我来发个位运算枚举子集。

题意

给一个 n 个数的集合,找出一个子集使其异或和最大,求出这个异或和。

思路

n 很小,考虑直接 2n 枚举。

定义 pi 为一个人能力的权重和,首先要算出 pi

只需要把第 i 个人所有能力的权重按位或起来就可以了。

需要注意的是,如果要用 1 << k - x 的方式来算 2kx,那么必须写成 1ull << k - x

因为 1 << k - x 里的 1 是 int 型的,把 int 型的数左移 60 位是未定义行为。

这样这个集合就求出来了,接下来我们要枚举子集。


我们用一个二进制数来表示每个数选不选,

具体地,s & (1 << i) == 1 代表选择第 i 个数。

现在需要枚举所有的 s,也就是所有不多于 n 位的二进制数。

可以发现,需要枚举 [0,2n) 之内的数。

对于每个 s,求出它所代表的的子集的异或和,取最大值即可。

代码

#include <cstdio>
unsigned long long p[50], s, u, ans, sum;int n, k;
int main()
{
    scanf("%d%d", &n, &k);u = 1 << n;
    for(int i = 0, t, x;i < n;++i)
    {
        scanf("%d", &t);
        while(t--) scanf("%d", &x), p[i] |= 1ull << k - x; //注意是 1ull
    }
    for(;s < u;++s) //枚举 s
    {
        sum = 0;
        for(int i = 0;i < n;++i)
            if(s & (1 << i)) sum ^= p[i]; //算出 s 代表的子集的异或和
        if(sum > ans) ans = sum; //更新最大值
    }
    printf("%lld", ans);
    return 0;
}
posted @   Jijidawang  阅读(25)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示