若
有
若
则
P4859 已经没有什么好害怕的了
给两个数列 , , 要求 两两匹配,使得 的个数减去 的个数等于 ,求总方案数。
先将 排序,定义 为前 个 中恰好有 个满足 的方案数,其他的均未匹配的方案数。
有 。
其中 为 中小于 的个数。
定义 为满足 的个数大于 的方案数, 表示满足 的个数等于 的方案数。
可以发现 在 ()中出现了 次。
有
#include <bits/stdc++.h> | |
using namespace std; | |
using ll = long long; | |
inline ll Max(ll x, ll y){return x > y ? x : y;} | |
const ll N = 2001; | |
const ll mod = 1e9 + 9; | |
ll n, c[N][N], f[N][N], g[N], a[N], b[N], mx[N], fac[N]; | |
void init_c(ll tt){ | |
c[0][0]=1; | |
for(ll i = 1; i <= tt; i++){ | |
c[i][0]=1; | |
for(ll j = 1; j <= tt; j++) | |
c[i][j] = (c[i-1][j] + c[i-1][j-1]) % mod; | |
} | |
} | |
void init_fac(ll tt){ | |
fac[0] = 1; | |
for(ll i = 1; i <= tt; i++) | |
fac[i] = fac[i-1] * i % mod; | |
} | |
ll fu(ll x){return x&1?-1:1;} | |
int main(){ | |
ll k; | |
cin>>n>>k; | |
for(ll i = 1; i <= n; i++) | |
cin >> a[i]; | |
for(ll i = 1; i <= n; i++) | |
cin >> b[i]; | |
sort(a+1, a+n+1); | |
sort(b+1, b+n+1); | |
init_c(n); | |
init_fac(n); | |
f[0][0]=1; | |
for(ll i = 1; i <= n; i++){ | |
mx[i] = lower_bound(b+1, b+n+1, a[i]) - b - 1; | |
f[i][0] = f[i-1][0]; | |
for(ll j = 1; j <= i; j++) | |
f[i][j] = (f[i-1][j] + f[i-1][j-1] * Max(0, (mx[i] - j + 1)) % mod) % mod; | |
} | |
ll x = (n + k) >> 1; | |
if((n+k)%2)cout<<0<<endl, exit(0); | |
ll ans = 0; | |
for(ll i = x; i <= n; i++) | |
ans = (ans + fu(i-x) * c[i][x] % mod * f[n][i] % mod * fac[n-i] % mod) % mod; | |
cout << (ans % mod + mod) % mod << endl; | |
return 0; | |
} |