嘟嘟嘟




题中给的\(k\)有点别扭,我们转换成\(a > b\)的对数是多少,这个用二元一次方程解出来是\(\frac{n + k}{2}\)。




然后考虑dp,令\(dp[i][j]\)表示前\(i\)个数中,有\(j\)对满足\(a > b\)的方案数,转移的时候考虑这一组是否满足\(a > b\)即可:\(dp[i][j] = dp[i - 1][j] + dp[i - 1][j - 1] * (num[i] - (j - 1))\)。其中\(num[i]\)表示比\(a[i]\)小的\(b[i]\)的个数。




求完这个还没有完事,因为我们只保证了有\(j\)个满足\(a > b\),而剩下的位置并不清楚。

于是令\(g[i] = dp[n][i] * (n - i)!\),表示\(n\)组匹配中,至少有\(i\)组满足\(a > b\)的方案数,因为剩下的\(n - i\)个位置是瞎排的,所以不知道是否会出现\(a > b\)。




令\(f[i]\)表示恰好有\(i\)个匹配满足\(a > b\),那么能列出\(g[k] = \sum _ {i = k} ^ {n} C_{i} ^ {k} f[i]\)(其实自己并不是十分懂这一步),然后通过二项式反演就可以求出\(f[k] = \sum _ {i = k} ^ {n} (-1) ^ {i - k} C_{i} ^ {k} g[i]\)。


#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<vector>
#include<stack>
#include<queue>
#include<assert.h>
using namespace std;
#define enter puts("")
#define space putchar(' ')
#define Mem(a, x) memset(a, x, sizeof(a))
#define In inline
typedef long long ll;
typedef double db;
const int INF = 0x3f3f3f3f;
const db eps = 1e-8;
const int maxn = 2e3 + 5;
const ll mod = 1e9 + 9;
In ll read()
{
ll ans = 0;
char ch = getchar(), last = ' ';
while(!isdigit(ch)) last = ch, ch = getchar();
while(isdigit(ch)) ans = (ans << 1) + (ans << 3) + ch - '0', ch = getchar();
if(last == '-') ans = -ans;
return ans;
}
In void write(ll x)
{
if(x < 0) x = -x, putchar('-');
if(x >= 10) write(x / 10);
putchar(x % 10 + '0');
}
In void MYFILE()
{
#ifndef mrclr
freopen("ha.in", "r", stdin);
freopen("ha.out", "w", stdout);
#endif
} int n, K, a[maxn], b[maxn], num[maxn]; In ll inc(ll a, ll b) {return a + b < mod ? a + b : a + b - mod;} ll fac[maxn], C[maxn][maxn];
In void init()
{
fac[0] = 1;
for(int i = 1; i <= n; ++i) fac[i] = fac[i - 1] * i % mod;
C[0][0] = 1;
for(int i = 1; i <= n; ++i)
{
C[i][0] = 1;
for(int j = 1; j <= i; ++j) C[i][j] = inc(C[i - 1][j - 1], C[i - 1][j]);
}
} ll dp[maxn][maxn]; int main()
{
MYFILE();
n = read(), K = (n + read()) >> 1;
init();
for(int i = 1; i <= n; ++i) a[i] = read();
for(int i = 1; i <= n; ++i) b[i] = read();
sort(a + 1, a + n + 1), sort(b + 1, b + n + 1);
for(int i = 1; i <= n; ++i) num[i] = lower_bound(b + 1, b + n + 1, a[i]) - b - 1;
dp[0][0] = 1;
for(int i = 1; i <= n; ++i)
{
dp[i][0] = dp[i - 1][0];
for(int j = 1; j <= i; ++j)
dp[i][j] = inc(dp[i - 1][j] % mod, dp[i - 1][j - 1] * (num[i] - j + 1) % mod);
}
ll ans = 0;
for(int i = K; i <= n; ++i)
{
int flg = (i - K) & 1;
ll tp = C[i][K] * fac[n - i] % mod * dp[n][i] % mod;
ans = inc(ans, flg ? mod - tp : tp);
}
write(ans), enter;
return 0;
}

最新文章

  1. web api :Action Results in Web API 2
  2. C# 禁止程序多个实例运行
  3. &quot;本地泛解析&quot;或者叫做”域名劫持泛解析“,做开发二级域名在内网测试
  4. 【BZOJ】2286: [Sdoi2011消耗战
  5. 利用JS实现手机访问PC网址自动跳转到wap网站
  6. google pinyin elmentary os
  7. Spring中通配符
  8. ios 8和iOS 9 适用的uidatepicker
  9. 基于视觉信息的网页分块算法(VIPS) - yysdsyl的专栏 - 博客频道 - CSDN.NET
  10. 训练 smallcorgi/Faster-RCNN_TF 模型(附ImageNet model百度云下载地址)
  11. 简单上手nodejs调用c++(c++和js的混合编程)
  12. Apache rewrite地址重写
  13. Leetcode#118. Pascal&#39;s Triangle(杨辉三角)
  14. C#---初学ActiveMQ中间件
  15. 解决Win8.1 IE11兼容性问题的方法
  16. P1494 [国家集训队]小Z的袜子(莫队算法)
  17. 利用MATLAB截取一张复杂图片中想要的区域
  18. 从零自学Java-7.使用数组存储信息
  19. kubeadm init 卡在 Created API client, waiting for the control plane to become ready
  20. 下载url地址的图片

热门文章

  1. 3.ASP.NET Core Docker学习-构建单机多容器环境
  2. MacBook使用HHKB键盘设置
  3. 通过Kubeadm搭建Kubernetes集群
  4. C# List&lt;&gt; Find相关接口学习
  5. vue拦截
  6. 1.Java集合-HashMap实现原理及源码分析
  7. vim文件时自动添加作者、时间、版权等信息
  8. C++自问
  9. linux设置自动同步服务器时间
  10. 【转】xshell 5评估期已过,不能访问的解决方案