G. One-Dimensional Puzzle

G. One-Dimensional Puzzle

You have a one-dimensional puzzle, all the elements of which need to be put in one row, connecting with each other. All the puzzle elements are completely white and distinguishable from each other only if they have different shapes.

Each element has straight borders at the top and bottom, and on the left and right it has connections, each of which can be a protrusion or a recess. You cannot rotate the elements.

You can see that there are exactly $4$ types of elements. Two elements can be connected if the right connection of the left element is opposite to the left connection of the right element.

All possible types of elements.

The puzzle contains $c_1, c_2, c_3, c_4$ elements of each type. The puzzle is considered complete if you have managed to combine all elements into one long chain. You want to know how many ways this can be done.

Input

The first line contains a single integer $t$ ($1 \le t \le 2 \cdot 10^5$) — the number of input test cases. The descriptions of the test cases follow.

The description of each test case contains $4$ integers $c_i$ ($0 \le c_i \le 10^6$) — the number of elements of each type, respectively.

It is guaranteed that the sum of $c_i$ for all test cases does not exceed $4 \cdot 10^6$.

Output

For each test case, print one integer — the number of possible ways to solve the puzzle.

Two methods are considered different if there is $i$, such that the types of elements at the $i$ position in these methods differ.

Since the answer can be very large, output it modulo $998244353$.

If it is impossible to solve the puzzle, print $0$.

Example

input

11
1 1 1 1
1 2 5 10
4 6 100 200
900000 900000 900000 900000
0 0 0 0
0 0 566 239
1 0 0 0
100 0 100 0
0 0 0 4
5 5 0 2
5 4 0 5

output

4
66
0
794100779
1
0
1
0
1
36
126

 

解题思路

  模拟一下可以发现任意一个合法方案中,只看 $1$ 和 $2$ 拼图的相对顺序的话,必然是交替出现的,即 $1 \, 2 \, 1 \, 2 \, 1 \ldots$ 或 $2 \, 1 \, 2 \, 1 \, 2 \ldots$。因为将 $3$ 或 $4$ 拼接到 $1$ 和 $2$ 左右两侧时,并不会改变图案左右两侧的凹凸性。所以如果 $|c_1 - c_2| \geq 2$ 则无解。

  同时可以发现 $3$ 只会出现在 $1$ 的右侧或 $2$ 的左侧,$4$ 只会出现在 $1$ 的左侧或 $2$ 的右侧,所以方案大致都是这样的形式:$$\ldots \; \overbrace{ \ldots 4 \ldots}^{\text{若干个 } 4} \, {\color{Red} 1} \, \overbrace{\ldots 3 \ldots}^{\text{若干个 } 3} \, {\color{Red} 2} \, \overbrace{\ldots 4 \ldots}^{\text{若干个 } 4} \, {\color{Red} 1} \, \overbrace{\ldots 3 \ldots}^{\text{若干个 } 3} \; \ldots$$

  另外可以发现 $3$ 和 $4$ 的放置是相互独立的,所以可以分别计算放置 $3$ 和 $4$ 的方案数,再通过乘法原理得到总的方案数。

  当 $c_1 \ne c_2$,只能是 $1 \, 2 \, \ldots 1$ 或 $2 \, 1 \, \ldots 2$ 中的一种,令 $m = \max\{c_1, c_2\}$,则可以放置 $3$ 和 $4$ 的位置均有 $m$ 个。先考虑放置 $3$ 的方案数,假设每个位置放置的数量为 $x_i \geq 0$,这相当于问 $x_1 + x_2 + \ldots + x_m = c_3$ 的解有多少组,根据隔板法知道有 $C_{c_3+m-1}^{m-1}$ 种。同理放置 $4$ 的方案数为 $C_{c_4+m-1}^{m-1}$。所以总的方案数为 $C_{c_3+m-1}^{m-1} \times C_{c_4+m-1}^{m-1}$。

  当 $c_1 = c_2$,那么可以是 $1 \, 2 \, \ldots 1 \, 2$ 或 $2 \, 1 \, \ldots 2 \, 1$ 这两种,对应到 $3$ 有 $m$ 个位置 $4$ 有 $m+1$ 个位置可放置,或 $4$ 有 $m$ 个位置 $3$ 有 $m+1$ 个位置可放置。把两种情况都考虑,则有 $C_{c_3+m-1}^{m-1} \times C_{c_4+m}^{m} + C_{c_3+m}^{m} \times C_{c_4+m-1}^{m-1}$ 种方案。另外需要特判 $c_1 = c_2 = 0$ 的情况,此时若 $c_3$ 和 $c_4$ 都不为 $0$ 则无解。

  AC 代码如下,时间复杂度为 $O(\max\{c_1, c_2\})$:

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;

const int mod = 998244353;

int qmi(int a, int k) {
    int ret = 1;
    while (k) {
        if (k & 1) ret = 1ll * ret * a % mod;
        a = 1ll * a * a % mod;
        k >>= 1;
    }
    return ret;
}

int C(int a, int b) {
    int u = 1, d = 1;
    for (int i = 1, j = a; i <= b; i++, j--) {
        u = 1ll * u * j % mod;
        d = 1ll * d * i % mod;
    }
    return 1ll * u * qmi(d, mod - 2) % mod;
}

void solve() {
    int a, b, c, d;
    scanf("%d %d %d %d", &a, &b, &c, &d);
    if (abs(a - b) >= 2) {
        printf("0\n");
        return;
    }
    int m = max(a, b);
    if (a != b) {
        printf("%d\n", 1ll * C(c + m - 1, m - 1) * C(d + m - 1, m - 1) % mod);
    }
    else {
        if (!m) printf("%d\n", !c || !d);
        else printf("%d\n", (1ll * C(c + m - 1, m - 1) * C(d + m, m) + 1ll * C(c + m, m) * C(d + m - 1, m - 1)) % mod);
    }
}

int main() {
    int t;
    scanf("%d", &t);
    while (t--) {
        solve();
    }
    
    return 0;
}

 

参考资料

  Codeforces Round 925 (Div. 3) A-G 比赛录屏+讲解(60分钟开始):https://www.bilibili.com/video/BV16p421d7xw/

posted @ 2024-02-14 20:19  onlyblues  阅读(61)  评论(1编辑  收藏  举报
Web Analytics