题目传送门
【考查点:容斥原理的理解,高维前缀和求解】
题意:给
个数,每个数都小于等于
, 求其中取任意个数&值为0的方案数?
题解:我们先求解&和不为零的情况。我们令
&
的所有
数目。对于每个
它们中任意取数&和都不为零。其方案数为
。
根据容斥原理所有&和不为0的方案数为
由于
然后求解f(x)过程就是一个求解高维前缀和过程。
ACcode
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int MOD=1e9+7;
const int N=1<<20;
int d[N];
LL p[N];
int bt[25],n,x;
int main()
{
for(int i=0;i<=20;i++)bt[i]=1<<i;
p[0]=1;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&x);
d[x]++;
p[i]=p[i-1]<<1;
if(p[i]>=MOD)
p[i]-=MOD;
}
for(int j=0;j<=20;j++)
for(int i=0;i<=1000000;i++)
{
if(i&bt[j])
d[i^bt[j]]+=d[i];
}
LL ans=0,cur;
for(int i=0;i<=1000000;i++)
{
if(d[i])
{
cur=p[d[i]]-1;
if(__builtin_popcount(i)&1)
ans=(ans+MOD+MOD-cur)%MOD;
else
ans=(ans+cur)%MOD;
}
}
printf("%lld\n",ans);
}