组合数学简单题
首先因为相邻两数的差不超过1,简言之就是1和3不能相邻,中间必须要使用2隔开
所以我们插板法,数字2就是那个板子,并枚举选i隔间放数字1
首先就是隔间的选法,因为可以最左或最右放非2,所以一共x2+1个可放隔间,方案数为Cix2+1
然后就是将1填入这i个空间且不能空,插板法得到方案数为Ci−1x1−1
最后再在x2+1−i个隔间中放3且可以空,继续插板(先补充x3个)得到方案数为Cx2−ix2+x3−i
相乘求和即可
AC代码
Details
#include<bits/stdc++.h>
using namespace std;
#define QAQ return
#define QWQ return 0;
#define ll long long
#define pii pair< int,int >
const int N=3e6+10, mod=998244353;
ll inv[N], jc[N], jc_inv[N];
inline ll C( int n,int m ){ QAQ jc[n]*jc_inv[m]%mod*jc_inv[n-m]%mod; }
int main()
{
ios::sync_with_stdio( false );
cin.tie( nullptr ), cout.tie( nullptr );
int x1, x2, x3;
cin>>x1>>x2>>x3;
jc[0]=1, jc[1]=1;
inv[0]=0, inv[1]=1;
jc_inv[0]=1, jc_inv[1]=1;
for( int i=2;i<=x1+x2+x3;i++ )
{
jc[i]=jc[i-1]*i%mod;
inv[i]=( -1ll*mod/i*inv[mod%i]%mod+mod )%mod;
jc_inv[i]=jc_inv[i-1]*inv[i]%mod;
}
ll ans=0;
for( int i=1;i<=x2;i++ ) if( x1-1 >= i-1 ) ( ans+=C( x2+1,i )*C( x1-1,i-1 )%mod*C( x3+x2-i,x3 ) )%=mod;
cout<<ans;
QWQ
}
时间复杂度:O(n)