CF 1312D. Count the Arrays

Count the Arrays

题意

要求计算出满足如下条件的数组的数量:

  1. 数组长度为\(n\),且这 \(n\) 个元素的取值均为 \([1, m]\)
  2. 数组中恰好有一对元素是相同的。
  3. 存在一个索引 \(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;
}
posted @ 2021-11-20 15:43  Horb7  阅读(38)  评论(0编辑  收藏  举报