gn=i=0n(ni)fng_n = \sum_{i=0}^n\dbinom{n}{i}f_n

fn=i=1n(ni)gnf_n=\sum_{i=1}^{n}\dbinom{n}{i}g_n

gi=j=in(ji)fjg_i=\sum_{j=i}^{n} \dbinom{j}{i}f_j

fi=j=in(ji)(1)jigjf_i=\sum_{j=i}^{n}\dbinom{j}{i}(-1)^{j-i}g_j

P4859 已经没有什么好害怕的了

给两个数列 aa, bb, 要求 ai,bia_i,b_i 两两匹配,使得 ai>bia_i>b_i 的个数减去 ai<bia_i<b_i 的个数等于 kk,求总方案数。

先将 a,ba,b 排序,定义 fi,jf_{i,j} 为前 iia[i]a[i] 中恰好有 jj 个满足 ai>bia_i>b_i 的方案数,其他的均未匹配的方案数。

fi,j=fi1,j+fi1,j1(ri(j1))f_{i,j} = f_{i-1,j} + f_{i-1,j-1}(r_i-(j-1))

其中 rir_ibb 中小于 aia_i 的个数。

定义 gig_i 为满足 aj>bja_j>b_j 的个数大于 ii 的方案数, GiG_i 表示满足 aj>bja_j>b_j 的个数等于 ii 的方案数。

可以发现 GiG_igjg_ji>ji>j)中出现了 (ij)\tbinom{i}{j} 次。

gi=fn,i(ni)!g_i=f_{n,i}(n-i)!

gi=j=in(ji)Gjg_i = \sum_{j=i}^{n}\dbinom{j}{i}G_j

Gi=j=in(ji)(1)jigjG_i = \sum_{j=i}^{n}\dbinom{j}{i}(-1)^{j-i}g_j

#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;
}