CF1569C Jury Meeting
CF1569C Jury Meeting
一道很简单的数学题, 虽然我写了半天...
因为严格次大值的数量一直不对...然后就 \(sort\) 了(真香).
我们设 \(n1\) 是最大值, \(n2\) 是次大值(不是严格次大值).
当 \(n1 - n2 \ge 2\) 时, 显然无解, 因为无论如何最大值一定会连续选两次.
当 \(n1 == n2\) 当最大值与次大值相等时, 也就是最大值不止一个时, 显然答案就是 \(n!\) , 因为所有解都合法.
接下来我们考虑一般情况, 也就是最大值只有一个, \(n2\) 是严格次大值时.
我们记录严格次大值的数量为 \(m\) , 当前方案合法当且仅当至少有 \(1\) 个严格次大值在最大值的右边, 这个似乎不是特别好求, 所以我们就用全部方案 - 非法方案.
非法方案很简单, 就是所有的严格次大值都在左边, 剩下的任意, 所以
\[ans = n! - \displaystyle \sum_{i = 0}^{n - m - 1} i! * (n - i - 1)! * \binom{n - m - 1}{i}
\]
\(code:\)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int read() {
int x = 0, f = 1;
char ch = getchar();
while (!isdigit(ch)) {
if (ch == '-') f = -1;
ch = getchar();
}
while (isdigit(ch)) {
x = (x << 1) + (x << 3) + (ch ^ 48);
ch = getchar();
}
return x * f;
}
const int N = 2e5 + 5, mod = 998244353;
ll ksm(ll a, int b) {
ll ans = 1;
while (b) {
if (b & 1) ans = ans * a % mod;
a = a * a % mod;
b >>= 1;
}
return ans;
}
ll fac[N], inv[N];
void init(int n) {
fac[0] = 1;
for (int i = 1; i <= n; i++) fac[i] = fac[i - 1] * i % mod;
inv[n] = ksm(fac[n], mod - 2);
for (int i = n - 1; i >= 0; i--) inv[i] = inv[i + 1] * (i + 1) % mod;
}
ll C(int n, int m) {
if (n < m || m < 0) return 0;
return fac[n] * inv[m] % mod * inv[n - m] % mod;
}
int n, a[N], n1, n2, m;
ll ans;
int main() {
init(N);
int T = read();
while (T--) {
n = read(); ans = n1 = n2 = m = 0;
for (int i = 1; i <= n; i++) a[i] = read();
sort(a + 1, a + n + 1);
n1 = a[n]; n2 = a[n - 1];
if (n1 - n2 >= 2) ans = 0;
else if (n1 == n2) ans = fac[n];
else {
for (int i = n - 1; a[i] == n2; i--) m++;
ans = fac[n];
for (int i = 0; i <= n - m - 1; i++) {
ans = ((ans - fac[i] * fac[n - i - 1] % mod * C(n - m - 1, i) % mod) % mod + mod) % mod;
}
}
printf("%lld\n", ans);
}
return 0;
}
看不见我看不见我看不见我