这题主要就是涉及到满足条件的组合数,
思路:从m个数中选择n-1个不同的数。由于里面的元素只有一个重复,而且重复的元素不能是最大值,那么就要从剩下的n-2个数中选择出一个最大值,下标为i。对于剩下的n-3个数,选x个排在最大值的左侧,这样的话,总共的情况数就是
C(n-1,m)*(n-2)*(2^(n-3))
那么代码就很简单了。但是问题来了,这个组合数会很大,要模除一个数。然后由于同余线性方程组没有除法,因此组合数要取逆元,也就是a^-1=a^(p-2)
求逆元的话就可以用快速幂来求,然后就是看代码了
需要特别注意的是,当n=2的时候,无法满足要求,以及n-1>m的时候,也是无法满足要求的。
#include <iostream>
#include <math.h>
using namespace std;
typedef long long ll;
const ll md = 998244353;
#define MAXN 200010
ll fact[MAXN];
ll qpow(ll x, ll k)
{
ll ans = 1;
x %= md;
while (k)
{
if (k & 1)
ans = (ans * x) % md;
x = (x * x) % md;
k >>= 1;
}
return ans%md;
}
ll c(ll a, ll b) //C(a,b)
{
return 1ll*(fact[a] * qpow((fact[b] * fact[a - b]) % md, md - 2)) % md; //模意义下的组合数,分母要取逆元
}
int main()
{
ll n, m;
cin >> n >> m;
if (n == 2 || n - 1 > m)
{
cout << 0 << endl;
return 0;
}
fact[0] = 1;
for (int i = 1; i <= 200000; ++i)
fact[i] = (i * fact[i - 1]) % md;
ll ans1 = c(m, n - 1);
ll ans2 = n - 2;
ll ans3 = qpow(2, n - 3);
ll ans = (ans1 * ans2) % md;
ans = (ans*ans3)%md;
cout << ans << endl;
}
欢迎关注我的公众号“灯珑”,让我们一起了解更多的事物~