Team Division
Team Division
差分性质
cntA代表 固定一个队伍数量为i时,有多少个人可以到这个队伍中
both代表 能去i 也能去n-i
这样就可以枚举A = i, B = n - i的情况,直接计算即可
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const ll MOD = 998244353;
const ll INF = 1e9;
const int N = 2e5 + 10;
ll fact[N], invfact[N];
ll modpow(ll a, ll b) {
ll r = 1;
while(b) {
if(b & 1) r = r * a % MOD;
a = a * a % MOD;
b >>= 1;
}
return r;
}
void init() {
fact[0] = 1;
for(int i = 1; i < N; i ++) fact[i] = fact[i-1] * i % MOD;
invfact[N-1] = modpow(fact[N-1], MOD-2);
for(int i = N - 2; i >= 0; i --) invfact[i] = invfact[i+1]*(i+1) % MOD;
}
ll C(int a, int b) {
return fact[a] * invfact[b] % MOD * invfact[a-b] % MOD;
}
void solve() {
init();
int n; cin >> n;
vector<int> cntA(n + 1, 0), both(n + 1, 0);
for(int i = 1; i <= n; i ++) {
int l, r; cin >> l >> r;
cntA[l] ++, cntA[r + 1] --;
int left = max(n - r, l), right = min(n - l, r);
if(left <= right) both[left] ++, both[right + 1] --;
}
for(int i = 1; i <= n; i ++) cntA[i] += cntA[i - 1], both[i] += both[i - 1];
ll ans = 0;
for(int i = 1; i < n; i ++) {
if(n - cntA[i] - cntA[n - i] + both[i] > 0) continue;
if(cntA[i] < i) continue;
int must = cntA[i] - both[i];
int x = i - must;
if(x < 0 || x > both[i]) continue;
ans = (ans + C(both[i], x)) % MOD;
}
cout << ans << "\n";
}
int main() {
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
solve();
return 0;
}

浙公网安备 33010602011771号