题解:AT_jag2018summer_day2_k Short LIS
先翻转整个排列,根据 Dilworth 定理,最长下降子序列长度不超过
注意到,如果可以用两条上升子序列覆盖
证明:前缀最大值肯定能构成一个上升子序列,如果剩下的数不是单调递增的,就必然有一对非前缀最大值
如果确定了
显然有
现在只需要处理
- 若前缀最大值
p_k<k ,则p_{1\dots k-1} 中必有一个数大于p_k ,p_k 不是前缀最大值,矛盾; - 反之,若某个非前缀最大值
p_k\ge k ,则p_{k+1\dots n} 中必有一个数小于p_k ,方案不合法,矛盾。
因此若
若
#include <iostream>
#include <atcoder/modint>
using namespace std;
using ll = atcoder::modint1000000007;
const int kN = 2e6 + 1;
int n, a, b;
ll ans, f[kN];
ll C(int n, int m) { return m < 0 ? 0 : f[n] / f[m] / f[n - m]; }
ll F(int p, int q) { return C(p + q, p) - C(p + q, p - 1); }
int main() {
cin.tie(0)->sync_with_stdio(0);
f[0] = 1;
for (int i = 1; i < kN; ++i) {
f[i] = f[i - 1] * i;
}
cin >> n >> a >> b, a = n - a, ++b;
if (b < a) {
swap(a, b);
}
cout << (F(a - 1, b - 1) * F(n - b, n - a)).val();
return 0;
}