我们固定了 AA 队中的人数之后一共会有三类人,分别是只能放 AA 的,只能放 BB 的,和 AABB 都能去的,这里可以用差分数组维护。(可以通过当前能去 AA 队的人数推出 BB 队的范围就是 nrn - rnln - l

这个时候我们可以通过容斥原理先判断一下当前情况合不合法,然后就是能去两个队的用组合数分配就好啦。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int mod = 998244353;
int fact[222222], invf[222222];
int fastpow(int a, int b)
{
int res = 1;
while (b) {
if (b & 1) {
res = (res * a) % mod;
}
b >>= 1;
a = (a * a) % mod;
}
return res;
}
void init(int n)
{
fact[0] = 1;
for (int i = 1; i <= n + 1; i++) {
fact[i] = (fact[i - 1] * i) % mod;
}
invf[n + 1] = fastpow(fact[n + 1], mod - 2);
for (int i = n; i >= 0; i--) {
invf[i] = (invf[i + 1] * (i + 1)) % mod;
}
return;
}
int C(int n, int m)
{
return ((fact[n] * invf[m]) % mod * invf[n - m]) % mod;
}
signed main()
{
int n;
cin >> n;
init(n + 111);
vector<int> d1(n + 2, 0), d2(n + 2, 0), d3(n + 2, 0);
for (int i = 0; i < n; i++) {
int l, r;
cin >> l >> r;
d1[l]++;
d1[r + 1]--;
d2[n - r]++;
d2[n - l + 1]--;
int tpl = max(l, n - r), tpr = min(r, n - l);
if (tpl <= tpr) {
d3[tpl]++;
d3[tpr + 1]--;
}
}
int ans = 0;
int cnt1 = 0, cnt2 = 0, cnt3 = 0;
for (int i = 1; i < n; i++) {
cnt1 += d1[i];
cnt2 += d2[i];
cnt3 += d3[i];
if (cnt1 + cnt2 - cnt3 < n)
continue;

int tp = cnt1 - cnt3;
if (tp <= i && i - tp <= cnt3) {
ans = (ans + C(cnt3, i - tp)) % mod;
}
}
cout << ans;
return 0;
}