Codeforces 1312D Count the Arrays
组合学得好, 玄学少不了, 本题的关键点在于除了一个数可以出现2次, 每个数都只能出现一次, 那就是说选定了数字就选定了顺序, 我们只需找到如何选择数字即可
因为有一个重复, 那就从\(m\)中选择\(n-1\)个, 即\(C^{n-1}_{m}\), \(n-1\)个中除了最大值, 要选择出一个是重复的数, 即\(C^1_{n-2}\), 那么, 可供我们自由排列的数就只有\(n-3\)个, 假设在最大值左边有\(i\)个, 即\(\sum^{n-3}_{i=0}C^i_{n-3} = 2^{n-3}\)
#include<bits/stdc++.h>
using namespace std;
#define ms(x,y) memset(x, y, sizeof(x))
#define lowbit(x) ((x)&(-x))
typedef long long LL;
typedef pair<int,int> pii;
const int N = 200000 + 5;
const int MOD = (int)998244353;
LL F[N], Finv[N], inv[N];//F是阶乘,Finv是逆元的阶乘
void init(){
inv[1] = 1;
for(int i = 2; i < N; i ++){
inv[i] = (MOD - MOD / i) * 1ll * inv[MOD % i] % MOD;
}
F[0] = Finv[0] = 1;
for(int i = 1; i < N; i ++){
F[i] = F[i-1] * 1ll * i % MOD;
Finv[i] = Finv[i-1] * 1ll * inv[i] % MOD;
}
}
LL comb(int n, int m){//comb(n, m)就是C(n, m)
if(m < 0 || m > n) return 0;
return F[n] * 1LL * Finv[n - m] % MOD * Finv[m] % MOD;
}
LL quick_pow(LL a, LL b) {
if(b < 0) return 0;
LL ret = 1;
while(b) {
if(b & 1) ret = (ret * a) % MOD;
a = (a * a) % MOD;
b >>= 1;
}
return ret;
}
void run_case() {
int n, m;
cin >> n >> m;
init();
LL ans = 0;
ans = comb(m, n-1) % MOD;
ans = (ans * (n-2)) % MOD;
ans = (ans * quick_pow(2, n-3)) % MOD;
cout << ans;
}
int main() {
ios::sync_with_stdio(false), cin.tie(0);
cout.flags(ios::fixed);cout.precision(2);
//int t; cin >> t;
//while(t--)
run_case();
cout.flush();
return 0;
}