Official

E - Count 123 Editorial by en_translator


Preparation

Let \(\mathrm{binom}(n, k)\) denote the number of ways to choose \(k\) out of \(n\) items, disregarding the order. Then

\[\mathrm{binom}(n, k) := \begin{cases} \frac{n!}{k!(n-k)!} & (n \geq k \geq 0) \\ 0 & (\mathrm{otherwise}) \end{cases}.\]

Let \(\mathrm{part}(n, k)\) denote the number of ways to split a sequence of \(n\) items into \(k\) non-empty chunks. Then

\[\mathrm{part}(n, k) := \mathrm{binom}(n-1,\ k-1).\]

Observations

The second condition is equivalent to: “\(1\) and \(3\) do not occur consecutively.”

From the sequence \(A\), consider the subsequence \(B\) obtained by extracting all \(1\) and \(3\). \(B\) falls into one of the following four forms; we can count each case and sum them up.

\(B\) starts and ends with \(1\)

Suppose \(B\) has \(i\) maximal chunks consisting of consecutive \(1\)s.

Then \(B\) has \((i-1)\) maximal chunks consisting of consecutive \(3\)s. The number of possible such \(B\)s is \(\mathrm{part}(X_1,\ i) \mathrm{part}(X_3,\ i-1)\).

Also, \(B\) has \((2i-2)\) positions where \(1\) and \(3\) occur adjacently. In \(A\), each such slot has at least one occurrence of \(2\) in between.

Therefore, considering the process of inserting the other \((X_2 - (2i-2))\) copies of \(2\)s at any positions in \(B\), which is of length \(X_1 + X_3\), and then inserting the \((2i-2)\) copies of necessary \(2\)s at appropriate positions, we find that the number of possible positions of \(B\) in \(A\) is \(\mathrm{binom}(X_1+X_2+X_3 - (i*2-2),\ X_1 + X_3)\).

Hence, the number can be obtained by evaluating \(\mathrm{part}(X_1,\ i) \mathrm{part}(X_3,\ i-1) \mathrm{binom}(X_1+X_2+X_3 - (i*2-2),\ X_1 + X_3)\) for all \(i\), and taking their sum.

\(B\) starts and ends with \(3\)

The same discussion as “\(B\) starts and ends with \(1\)” case applies, by swapping \(X_1\) and \(X_3\).

\(B\) starts with \(1\) and ends with \(3\)

If \(B\) has \(i\) maximal chunks consisting of consecutive \(1\)s, it has \(i\) maximal chunks of consecutive \(3\)s, and \((2i-1)\) positions where \(1\) and \(3\) occur adjacently.

Therefore, the number of possible \(B\)s is \(\mathrm{part}(X_1,\ i) \mathrm{part}(X_3,\ i)\), and the number of positions of \(B\) in \(A\) is \( \mathrm{binom}(X_1+X_2+X_3 - (i*2-1),\ X_1 + X_3)\). We can find their product for all \(i\) and take their sum.

\(B\) starts with \(3\) and ends with \(1\)

The count is identical to “\(B\) starts with \(1\) and ends with \(3\)” case.

Implementation note

Let \(N := X_1 + X_2 + X_3\).

By precalculating the values of \(k!\) and their inverses for all \(0 \leq k \leq N\) in a total of \(N + \log(MOD)\) time, any necessary values of binomial coefficients can be found in \(O(1)\) time per query.

Sample code (C++)

#include <iostream>
using std::cin;
using std::cout;
using std::cerr;
using std::endl;
#include <vector>
using std::vector;
using std::pair;
using std::make_pair;
using std::min;
using std::max;
#include <algorithm>
using std::sort;
#include <deque>
using std::deque;
#include <cassert>

#ifdef DEBUG
const int debug = 1;
#else
const int debug = 0;
#endif

typedef long long int ll;
typedef pair<ll, ll> pr;

#include <atcoder/modint>
using mint = atcoder::modint998244353;

ll x1, x2, x3;

vector<mint> frac, invf;
void f_init (const ll n) {
	frac.resize(n+1);
	invf.resize(n+1);

	frac[0] = 1;
	for (ll i = 1; i <= n; i++) {
		frac[i] = frac[i-1] * i;
	}
	invf[n] = frac[n].inv();
	for (ll i = n; i >= 1; i--) {
		invf[i-1] = invf[i] * i;
	}
}
mint ncr (ll n, ll r) {
	if (n < 0 || n < r) return 0;
	return frac[n] * invf[r] * invf[n-r];
}
mint part1 (ll x, ll p) {
	return ncr(x-1, p-1);
}

void solve () {
	f_init(x1 + x2 + x3 + 10);

	mint ans = 0;

	// 13131...1
	for (ll i = 2; i <= x1; i++) {
		ans += part1(x1, i) * part1(x3, i-1) * ncr(x1+x2+x3 - (i*2-2), x1 + x3);
	}
	// 31313...3
	for (ll i = 2; i <= x3; i++) {
		ans += part1(x3, i) * part1(x1, i-1) * ncr(x1+x2+x3 - (i*2-2), x1 + x3);
	}
	// 1313...13, 3131...31
	for (ll i = 1; i <= min(x1, x3); i++) {
		ans += 2 * part1(x1, i) * part1(x3, i) * ncr(x1+x2+x3 - (i*2-1), x1 + x3);
	}

	cout << ans.val() << "\n";
}

int main (void) {
	std::cin.tie(nullptr);
	std::ios_base::sync_with_stdio(false);

	cin >> x1 >> x2 >> x3;

	solve();
	

	return 0;
}

posted:
last update: