ABC405E: Fruit Lineup
解法
\(f(n,m)\) 表示将 \(m\) 个字母插入到 \(n\) 个空隙之中。
\(f(n,m)=C_{n+m-1}^{n-1}\)
证明
可以发现 \(f\) 就相当于将 \(m\) 个苹果放到 \(n\) 个盒子里。
通过栅栏法,可以推断出该式等于 \(C_{n+m-1}^{n-1}\)。
首先,我们把 \(A\) 和 \(D\) 先排成 \(AAA\dots DDD\dots\) 这样。
接下去再枚举在 \(A\) 和 \(D\) 中间的 \(B\) 的数量 \(x\)。
然后在计算剩余的 \(B\) 放入 \(A\) 当中的方案数 \(f(A,B-x)\)
最后在计算将 \(C\) 插入到 \(A\) 后面的方案数 \(f(D+x+1,c)\)
再两两相乘再相加即可
代码
#include <bits/stdc++.h>
#define int long long
const int N = 3e6 + 5;
const int Mod = 998244353;
using namespace std;
int a, b, c, d;
int ans;
int fac[N], ifac[N];
int qpow(int a, int b)
{
int res = 1;
while (b > 0)
{
if (b & 1)
{
res = res * a;
res %= Mod;
}
a = a * a;
a %= Mod;
b >>= 1;
}
return res;
}
void init()
{
fac[0] = 1;
for (int i = 1; i < N; i++)
{
fac[i] = fac[i - 1] * i;
fac[i] %= Mod;
}
ifac[N - 1] = qpow(fac[N - 1], Mod - 2);
for (int i = N - 2; i >= 0; i--)
{
ifac[i] = ifac[i + 1] * (i + 1);
ifac[i] %= Mod;
}
}
int A(int n, int m)
{
if (m < 0 || m > n)
{
return 0;
}
return fac[n] * ifac[m] % Mod;
}
int C(int n, int m)
{
if (m < 0 || m > n)
{
return 0;
}
return fac[n] * ifac[m] % Mod * ifac[n - m] % Mod;
}
int f(int n, int m)
{
return C(n + m - 1, n - 1);
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
init();
cin >> a >> b >> c >> d;
for (int i = 0; i <= b; i++)
{
ans += f(a, b - i) * f(d + i + 1, c) % Mod;
ans %= Mod;
}
cout << ans;
return 0;
}

浙公网安备 33010602011771号