使用Bitmasking包含排除

时间:2015-09-18 08:56:53

标签: algorithm data-structures bit-manipulation

N个非负整数a1,a2,...,an。我们将一系列索引i1,i2,...,ik(1≤i1

存在多少个组ai1 & ai2 & ... & aik = 0 (1 ≤ k ≤ n).

操作x& y表示两个数字的按位AND运算。Messenger Plugin

方法: 在这个问题中使用包含 - 排除原则。

f(x)为数字i的计数,其中Ai& x = x。

g(x)是x 的二进制表示中的1的数字。然后答案等于。

(-1)^g(x)*2^f(x)

代码:

for(int i=0;i<20;i++) {
        for(int j=0;j<(1<<20);j++) {
            if(0 == (j & (1<<i))) {
                cnt[j | (1<<i)] += cnt[j];
            }
        }
    }

最后:

for(int i=0;i<(1<<20);i++) {
        int mask = 20 % 2;
        for(int j=0;j<20;j++) if(i & (1<<j)) mask ^= 1;

        if(mask == 0) ret = (ret + pows[cnt[i]]) % MOD;
        else ret = (ret + MOD - pows[cnt[i]]) % MOD;
    }

为什么这件事cnt[j | (1<<i)] += cnt[j]和 第二个循环是如何工作的以及如何应用包含 - 排除原则是在最后一个循环中。我无法想象集合形成,即如何描绘交叉点B

0 个答案:

没有答案