title
Simplify the meaning of the questions:
Two columns \ (\ {A_N \} \) , \ (\ {B_n \} \) , seeking \ (a_i> b_i \) number of groups just ratio \ (b_i> a_i \) the number of set of multi \ (K \) the number of cases of group.
analysis
Ask what topics can be transformed, but also for convenience:
Order \ (K = \ + K FRAC {n-2}} {\) , i.e. there is just \ (K \) group is larger than the tablet candy ( \ (a_i> B_i \) ).
Obviously you want to \ (a_i, b_i \) in ascending order.
Consider \ (a_i \) the impact of:
- If \ (a_i \) matches \ (B, a_i> B \) , then for \ (a_j, J> I \) , it matches \ (B, a_j> B \) . 1 less the number of programs;
- If \ (a_i \) matches \ (b, a_i <b \) ...... once again be classified discussions, the state is difficult to record.
So, we \ (Dp \) when consider the first of \ (a_i \) , last second of uniform distribution.
Set \ (g_ {i, j} \) representing the forward \ (I \) a \ (A \) , there are \ (J \) th number of a first embodiment .
State transition equation is:
\ [G_ {I, J} = {I-G_. 1, J +} (r_i- (-J. 1)). 1-G_ {I, J-}. 1 (b r_i represented in less than a_i number) \]
then, we can make
\ [f_i = (ni)!
g_ {n, i} \] is the \ (Ni \) arbitrary assignment did not match, to give at least \ (I \) th The answer \ (F_i \) .
So just \ (I \) th answer can be obtained from the large to the small recursion:
\ [{J} = I + C. 1 ^ = i_jans_j ans_i f_i- \ SUM n-^ {} _ \]
code
#include<bits/stdc++.h>
typedef long long ll;
const int maxn=2110,mod=1e9+9;
namespace IO
{
char buf[1<<15],*fs,*ft;
inline char getc() { return (ft==fs&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),ft==fs))?0:*fs++; }
template<typename T>inline void read(T &x)
{
x=0;
T f=1, ch=getchar();
while (!isdigit(ch) && ch^'-') ch=getchar();
if (ch=='-') f=-1, ch=getchar();
while (isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48), ch=getchar();
x*=f;
}
char Out[1<<24],*fe=Out;
inline void flush() { fwrite(Out,1,fe-Out,stdout); fe=Out; }
template<typename T>inline void write(T x)
{
if (!x) *fe++=48;
if (x<0) *fe++='-', x=-x;
T num=0, ch[20];
while (x) ch[++num]=x%10+48, x/=10;
while (num) *fe++=ch[num--];
*fe++='\n';
}
}
using IO::read;
using IO::write;
inline ll Quick_power(ll a,ll b)
{
ll ans=1;
while (b)
{
if (b&1) ans=ans*a%mod;
a=a*a%mod;
b>>=1;
}
return ans;
}
ll fac[maxn],inv[maxn];
inline ll C(int n,int m)
{
if (m==-1) return n==-1;
return fac[n]*inv[m]%mod*inv[n-m]%mod;
}
int a[maxn],b[maxn],r[maxn];
ll g[maxn][maxn],f[maxn],ans[maxn];
int main()
{
int n,K;read(n);read(K);
fac[0]=1;
for (int i=1; i<=maxn-1; ++i) fac[i]=fac[i-1]*i%mod;
inv[maxn-1]=Quick_power(fac[maxn-1],mod-2);
for (int i=maxn-2; i>=0; --i) inv[i]=inv[i+1]*(i+1)%mod;
if ((n+K)&1) return puts("0"),0;
K=(n+K)>>1;
for (int i=1; i<=n; ++i) read(a[i]);
for (int i=1; i<=n; ++i) read(b[i]);
std::sort(a+1,a+n+1);
std::sort(b+1,b+n+1);
for (int i=1, c=0; i<=n; ++i)
{
while (c<n && b[c+1]<a[i]) ++c;
r[i]=c;
}
g[0][0]=1;
for (int i=1; i<=n; ++i)
for (int j=0; j<=i; ++j) g[i][j]=(g[i-1][j]+(j ? 1ll*(r[i]-j+1)*g[i-1][j-1]%mod : 0ll))%mod;
for (int i=0; i<=n; ++i) f[i]=g[n][i]*fac[n-i]%mod;
for (int i=n; i>=K; --i)
{
ans[i]=f[i];
for (int j=i+1; j<=n; ++j) ans[i]=(ans[i]-ans[j]*C(j,i)%mod+mod)%mod;
}
write(ans[K]);
IO::flush();
return 0;
}