显示代码纯文本
#include "bits/stdc++.h"
using i64 = long long;
constexpr int P = 1e9 + 7;
int norm(int x) {
if (x < 0)
x += P;
if (x >= P)
x -= P;
return x;
}
template <class T>
T power(T a, i64 b) {
T res = 1;
for (; b; b /= 2, a *= a)
if (b % 2)
res *= a;
return res;
}
struct Z {
int x;
Z (int x = 0) : x(norm(x)) { }
Z (i64 x) : x(norm(x % P)) { }
int val() const {
return x;
}
Z inv() const {
assert(x != 0);
return power(*this, P - 2);
}
Z & operator *= (const Z &rhs) {
x = i64(x) * rhs.x % P;
return *this;
}
Z & operator += (const Z &rhs) {
x = norm(x + rhs.x);
return *this;
}
Z & operator -= (const Z &rhs) {
x = norm(x - rhs.x);
return *this;
}
Z & operator /= (const Z &rhs) {
return *this *= rhs.inv();
}
friend Z operator * (const Z &lhs, const Z &rhs) {
Z res = lhs;
res *= rhs;
return res;
}
friend Z operator + (const Z &lhs, const Z &rhs) {
Z res = lhs;
res += rhs;
return res;
}
friend Z operator - (const Z &lhs, const Z &rhs) {
Z res = lhs;
res -= rhs;
return res;
}
friend Z operator / (const Z &lhs, const Z &rhs) {
Z res = lhs;
res /= rhs;
return res;
}
friend std::istream & operator >> (std::istream &is, Z &a) {
i64 v;
is >> v;
a = Z(v);
return is;
}
friend std::ostream & operator << (std::ostream &os, const Z &a) {
return os << a.val();
}
};
using PII = std::pair<int, int>;
const int N = 6010;
int n;
Z f[2][N][2];
PII a[N];
int main() {
freopen("usaco_20Dec_sleep.in", "r", stdin);
freopen("usaco_20Dec_sleep.out", "w", stdout);
std::cin >> n;
for (int i = 1; i <= n; ++ i) {
auto& [x, y] = a[i];
std::cin >> x, y = 0;
}
for (int i = n + 1; i <= 2 * n; ++ i) {
auto& [x, y] = a[i];
std::cin >> x, y = 1;
}
std::sort(a + 1, a + 1 + n * 2);
f[0][0][1] = 1;
for (int i = 1; i <= 2 * n; ++ i) {
auto [_, x] = a[i];
memset(f[i & 1], 0, sizeof f[i & 1]);
if (x == 0) {
for (int j = 0; j <= n; ++ j) {
if (j) f[i & 1][j][0] += f[(i + 1) & 1][j - 1][0];
if (j) f[i & 1][j][1] += f[(i + 1) & 1][j - 1][1];
f[i & 1][j][0] += f[(i + 1) & 1][j][0] + f[(i + 1) & 1][j][1];
}
} else {
for (int j = 0; j <= n; ++ j) {
f[i & 1][j][1] += f[(i + 1) & 1][j][1] + f[(i + 1) & 1][j + 1][1] * Z(j + 1);
f[i & 1][j][0] += f[(i + 1) & 1][j + 1][0] * Z(j + 1);
}
}
}
std::cout << f[(n * 2) & 1][0][0] + f[(n * 2) & 1][0][1] << '\n';
return 0;
}