# 5322: [Jxoi2018]排序问题

每次选一个出现次数最小的。

```#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cmath>
#include<cctype>
#include<set>
#include<queue>
#include<vector>
#include<map>
#define pa pair<int,int>
using namespace std;
typedef long long LL;

int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f;
}
const int mod = 998244353;
int fac[10200005], a[200005], b[200005];

int ksm(int a,int b) {
int res = 1;
while (b) {
if (b & 1) res = 1ll * res * a % mod;
a = 1ll * a * a % mod;
b >>= 1;
}
return res;
}
void solve() {
int n = read(), m = read(), l = read(), r = read(), tot = 0, cnt = 0, f = r - l + 1, ans = 1;
for (int i = 1; i <= n; ++i) a[i] = read();
sort(a + 1, a + n + 1);

for (int i = 1, j = 1; i <= n; i = j) {
while (j <= n && a[i] == a[j]) j ++;
if (l <= a[i] && a[i] <= r) b[++tot] = j - i, f --;
else ans = 1ll * ans * fac[j - i] % mod;
}

sort(b + 1, b + tot + 1);
for (int i = 1, j = 1; i <= tot; i = j) {
while (j <= tot && b[i] == b[j]) j ++;
++cnt; a[cnt] = b[i], b[cnt] = j - i;
}
a[++cnt] = 1e9, b[cnt] = 1;

for (int i = 1, M = m; i <= cnt; ++i) {
LL c = a[i] - a[i - 1], t = c * f;
if (t > M) {
int x = a[i - 1] + (M / f), y = M % f;
ans = 1ll * ans * ksm(fac[x], f - y) % mod * ksm(fac[x + 1], y) % mod;
for (int j = i; j < cnt; ++j)
ans = 1ll * ans * ksm(fac[a[j]], b[j]) % mod;
break;
}
M -= t, f += b[i];
}
ans = 1ll * fac[n + m] * ksm(ans, mod - 2) % mod;
printf("%d\n", ans);
}
int main() {
fac[0] = 1;
for (int i = 1; i <= 10200000; ++i) fac[i] = 1ll * fac[i - 1] * i % mod;
for (int T = read(); T --; solve());
return 0;
}```

0条评论