Blog
賽場上差一點做出來。
首先發現左右兩部分是比較獨立的,所以可以分開計算後合併。
注意到我們可以把整個數集分成左右兩部分,即 \(\binom{n - 1}{p_{m1} - 1}\)。
然後我們不妨只考慮左邊。
發現左邊的最大值也已經確定,且最大值右邊的所有數可以隨便選,即 \(\binom{p_{i + 1} - 2}{p_i - 1}\)。
由於內部需要換順序,所以還要乘上 \((p_{i + 1} - p_i - 1)!\)。
右邊同理。最後的答案即為全部的乘積。
/*******************************
| Author: DE_aemmprty
| Problem: E. Girl Permutation
| Contest: Codeforces Round 936 (Div. 2)
| URL: https://codeforces.com/contest/1946/problem/E
| When: 2024-03-22 22:37:51
|
| Memory: 256 MB
| Time: 2000 ms
*******************************/
#include <bits/stdc++.h>
using namespace std;
long long read() {
char c = getchar();
long long x = 0, p = 1;
while ((c < '0' || c > '9') && c != '-') c = getchar();
if (c == '-') p = -1, c = getchar();
while (c >= '0' && c <= '9')
x = (x << 1) + (x << 3) + (c ^ 48), c = getchar();
return x * p;
}
const int N = 2e5 + 7;
const long long mod = 1e9 + 7;
int n, m1, m2;
int p[N], q[N];
long long fac[N];
long long ksm(long long x, long long y) {
long long res = 1;
for (; y; y >>= 1, (x *= x) %= mod)
if (y & 1)
(res *= x) %= mod;
return res;
}
long long C(long long x, long long y) {
if (x < y) return 0;
return fac[x] * ksm(fac[y] * fac[x - y] % mod, mod - 2) % mod;
}
void solve() {
n = read(), m1 = read(), m2 = read();
for (int i = 1; i <= m1; i ++) p[i] = read();
for (int i = 1; i <= m2; i ++) q[m2 - i + 1] = n - read() + 1;
if (p[m1] + q[m2] != n + 1 || p[1] != 1 || q[1] != 1) {
cout << 0 << '\n';
return ;
}
long long res = 1ll;
for (int i = 1; i < m1; i ++) {
int siz = p[i + 1] - p[i] - 1;
res = res * fac[siz] % mod * C(p[i + 1] - 2, p[i] - 1) % mod;
}
long long res2 = 1ll;
for (int i = 1; i < m2; i ++) {
int siz = q[i + 1] - q[i] - 1;
res2 = res2 * fac[siz] % mod * C(q[i + 1] - 2, q[i] - 1) % mod;
}
cout << res * res2 % mod * C(n - 1, p[m1] - 1) % mod << '\n';
}
signed main() {
int t = 1;
t = read();
fac[0] = 1;
for (int i = 1; i <= 200000; i ++) fac[i] = fac[i - 1] * i % mod;
while (t --) solve();
return 0;
}