我们先不考虑重排,最后除一个 就可以了
题意:值域在
间,选择
个不同的集合,使得每一个元素的出现次数为偶数
假设要选择
个集合,如果我们定下来
个,那么为了满足每一个元素都是偶数的限制,最后一个集合是确定的
大力
,令
表示选择
个集合且合法的方案数,容斥转移
需要减去前
个集合已经满足最后一个为空,以及最后一个钦定的与前面某一个集合相同的方案数
第一个就是
,第二个枚举重复的位置
注意集合间是有序的
#include<bits/stdc++.h>
#define cs const
using namespace std;
cs int Mod = 100000007;
cs int N = 1e6 + 5;
int add(int a, int b){ return a + b >= Mod ? a + b - Mod : a + b; }
int mul(int a, int b){ return 1ll * a * b % Mod; }
int ksm(int a, int b){ int ans = 1; for(;b;b>>=1,a=mul(a,a)) if(b&1) ans = mul(ans, a); return ans; }
int dec(int a, int b){ return a - b < 0 ? a - b + Mod : a - b; }
int n, m, fac[N], f[N];
int main(){
scanf("%d%d", &n, &m);
int up = dec(ksm(2, n),1); fac[0] = 1; int inv = 1;
for(int i = 1; i <= m; i++) inv = mul(inv, i); inv = ksm(inv, Mod-2);
for(int i = 1; i <= m; i++) fac[i] = mul(fac[i - 1], (up - i + 1));
f[0] = 1;
for(int i = 2; i <= m; i++){
f[i] = dec(fac[i - 1], add(f[i - 1], mul(mul(i-1, dec(up,i-2)), f[i-2])));
} cout << mul(f[m], inv); return 0;
}