题目大意:给定n个数,问有多少子序列使得子序列中的数&起来=0
做法:显然的容斥题目
ans=2^n-1-(至少1位为1-至少两位为1+至少3位为1......)
我们考虑用dp[i]表示包含i这个状态的数有多少个
显然我们可以枚举所有可能的有1的状态
for i=1 to 1e6 do begin
ans=2^n-1-sigma((-1)^g[i]*(2^dp[i]-1))
其中g[i]表示i这个状态下有几个1
显然包含i这个状态的数都可以选择,只要选的是这dp[i]个数
那么至少i状态这几位都是1
代码:
#include<bits/stdc++.h>
#define Mod 1000000007
#define N 1000005
using namespace std;
int n,bin[2*N],dp[2*N],x;
int main(){
scanf("%d",&n);
bin[0]=1;
for (int i=1;i<=1000000;i++) bin[i]=1ll*bin[i-1]*2%Mod;
for (int i=1;i<=n;i++) scanf("%d",&x),dp[x]++;
for (int j=0;j<=20;j++)
for (int i=1;i<=1000000;i++)//dp[i]表示包含i的数有多少
if ((1<<j)&i) (dp[i^(1<<j)]+=dp[i])%=Mod;
int ans=0;
for (int i=0;i<=1000000;i++){
int opt=1;
for (int j=0;j<=20;j++)
if ((1<<j)&i) opt=-opt;
ans=1ll*(ans+(1ll*opt*(bin[dp[i]]-1)%Mod))%Mod;
ans=(ans+Mod)%Mod;
}
printf("%d\n",ans%Mod);
return 0;
}