CF 1312D. Count the Arrays
Count the Arrays
题意
要求计算出满足如下条件的数组的数量:
- 数组长度为\(n\),且这 \(n\) 个元素的取值均为 \([1, m]\) 。
- 数组中恰好有一对元素是相同的。
- 存在一个索引 \(i\) ,满足 \([1, i]\) 严格上升, \([i, n]\) 严格下降。
分析
首先只有一对元素是相同的,那么有 \(n-1\) 个元素是互不相同的,选个方案有 \(C(m, n-1)\) 。
然后对于那个重复的元素,它不能和最大值相同,所以有 \(n-2\) 中选法。
为了满足第三个条件,首先重复的元素一定是放在最大值的左右两边的,对于剩下 \(n-3\) 个元素,
由于互不相同,所以对于每个元素都有两种方案,放在最大值左边或者右边,一定能满足单调性。
所以总方案数为 \(C(m, n-1) \times (n-2) \times 2^{n-3}\) 。
Code
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 200010, mod = 998244353;
typedef long long ll;
int qmi (int a, int k, int p)
{
int res = 1;
for (a %= p; k; k >>= 1, a = (ll)a * a % p)
if (k & 1) res = (ll)res * a % p;
return res;
}
int fac[N], infac[N];
void get_fac ()
{
fac[0] = infac[0] = 1;
for (int i = 1; i < N; i ++ )
{
fac[i] = (ll)i * fac[i-1] % mod;
infac[i] = (ll)qmi(i, mod-2, mod) * infac[i-1] % mod;
}
}
int C (int n, int k)
{
return (ll)fac[n] * infac[k] % mod * infac[n-k] % mod;
}
signed main ()
{
int n, m, ret = 0; cin >> n >> m;
get_fac();
if (n == 2) return cout << "0\n", 0;
cout << (ll) C(m, n-1) * (n-2) % mod * qmi(2, n-3, mod) % mod << '\n';
return 0;
}