题意:在 $n$ 个数的 $2^n-1$ 个非空子集中选取 $m$ 个,且必须满足:
1. $m$ 个子集两两不同.
2. 每个数在 $m$ 个子集中出现总次数为偶数.
3. 每个子集非空.
令 $f[i]$ 表示选出了 $i$ 个集合且满足了上述 3 条限制的方案数.
直接求 $f[i]$ 比较困难,考虑容斥:
如果前 $i-1$ 个集合确定,那么集合 $i$ 也唯一确定 (即前 $i-1$ 个中出现奇数次的数).
总:$A_{2^n-1}^{i-1}$.
有 2 种情况不合法:1. 集合 $i$ 为空集 2. 与前面的一个集合相同.
集合 $i$ 为空集,意味着前 $i-1$ 个集合中没有出现次数为奇数的数字,即 $f[i-1].$
集合 $i$ 与一个集合 $j$ 相同,意味着除去集合 $i,j$ 之外的集合是合法的,即 $f[i-2].$
而 $i$ 集合有 $2^n-1-(i-2)$ 种选取方式,所以这部分不合法的方案数是:$[2^n-1-(i-2)] imes f[i-2] imes (i-1)$.
由于上述推导过程中默认集合是有序的,所以答案还要除一个 $m!$.
#include <bits/stdc++.h>
#define N 1000007
#define ll long long
#define mod 100000007
#define setIO(s) freopen(s".in","r",stdin)
using namespace std;
int qpow(int x,int y)
{
int tmp=1;
for(;y;y>>=1,x=(ll)x*x%mod)
if(y&1) tmp=(ll)tmp*x%mod;
return tmp;
}
int A[N],f[N];
int main()
{
// setIO("input");
int i,j,n,m,inv;
scanf("%d%d",&n,&m);
inv=A[0]=1;
for(i=2;i<=m;++i) inv=(ll)i*inv%mod;
inv=qpow(inv,mod-2);
int mx=(qpow(2,n)-1+mod)%mod;
for(i=1;i<=m;++i)
A[i]=(ll)A[i-1]*(mx-i+1+mod)%mod;
f[0]=1,f[1]=0;
for(i=2;i<=m;++i)
{
f[i]=(ll)(A[i-1]-f[i-1]+mod)%mod;
f[i]=(ll)(f[i]-(ll)f[i-2]*(i-1)%mod*(qpow(2,n)-1-(i-2)+mod)%mod+mod)%mod;
}
printf("%d
",(ll)f[m]*inv%mod);
return 0;
}