Educational Codeforces Round 83 D. Count the Arrays(组合,逆元,快速幂)

题意:

从 m 个数中选 n - 1 个数组成先增后减的长为 n 的数组。

思路:

因为 n 个数中有两个数相同,所以每种情况实际上只有 n - 1 个不同的数——$c_m^{n - 1}$,

除去最大数,相同的数有 n - 2 种可能——${n-2}$,

最大数、相同的数排好后,剩余 n - 3 个数可能在最大数左边或右边——${2^{n - 3}}$,

所以答案即为:${(n-2)}{2^{n-3}}c_m^{n-1}$。

对组合数的阶乘公式进行化简,拆分为 n - 1 个分式,使用费马小定理计算逆元(取模意义下的倒数)。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
  
const ll mod=998244353;

ll qpow(ll a,ll b){ 
    ll res=1;
while(b){ if(b&1) (res*=a)%=mod; (a*=a)%=mod; b>>=1; } return res; } int main() { ll n,m;cin>>n>>m; if(n==2){ cout<<"0 "; }else{ ll ans=(n-2)*qpow(2,n-3)%mod; for(ll i=0;i<=n-2;i++) ans=ans*(m-i)%mod*qpow((n-1-i),mod-2)%mod; cout<<ans<<endl; } return 0; }
原文地址:https://www.cnblogs.com/Kanoon/p/12463777.html