1. CZday3C
给定有m个数的集合,从其中任选一个子集满足全部&后不为零,问方案数。
考虑对二进制位容斥,问题转化为求包含某个二进制位集合的数的个数,通过类似FMT的DP求解。
1 #include<bits/stdc++.h> 2 #define mo 1000000007 3 #define ll long long 4 using namespace std; 5 ll m,n,k,f[1100010],g[1100010],x,ans; 6 ll po(ll x,ll y){ll z=1;while (y){if (y%2==1)z=(x*z)%mo;x=(x*x)%mo;y/=2;}return z;} 7 int main(){ 8 freopen("loneliness.in","r",stdin); 9 freopen("loneliness.out","w",stdout); 10 cin>>n; 11 cin>>n>>m>>k; 12 for (int i=1;i<=m;i++){scanf("%d",&x);g[x]++;} 13 f[0]=-1; 14 for (int i=0;i<(1<<n);i++) 15 for (int j=1;j<(1<<n);j*=2) 16 if ((i&j)==0)f[i+j]=f[i]*(-1); 17 for (int i=1;i<(1<<n);i*=2) 18 for (int j=0;j<(1<<n);j++) 19 if ((i&j)!=0) g[j-i]+=g[j]; 20 for (int i=1;i<(1<<n);i++)ans=(ans+f[i]*po(g[i],k)+mo)%mo; 21 cout<<ans<<endl; 22 return 0; 23 }