当然得先分析题目的情况
类型1,2的数量差不能大于1:
样例3失败解释:
4 6 100 200
第六个型号2是没法再放进去的,所以可以分析出 类型1与类型2之间的差不能超过1
类型3,4可以自己拼自己;
3可以在1 2间,4 在2 1间:
1 2可以拼在一起,也可以在1 2 之间插入若干个3。
4同理。
所以题目问有多少种情况。
当1,2数目不同时:
// 1 2 1
//4 3 4 3
// 2 1 2
//3 4 3 4
(设a,b,c,d分别是1,2,3,4类型的数目)
可以看出对3和4来说可以插入的位置数目是相同的,为max(a,b)
那么问题等价于若干个盒子,我们把一对球放入盒子中,有多少种放法。(3和4的方法互补干扰,放法之积即为答案。)
而且1 2 之间可以为空,“隔板法”去放3是不行的(隔板法把n个分成若干份,每份至少为1个)。
比如c个球放入a个盒子,这里我们可以先欠做法:
先欠做法:
我们放c+a个球,最后每个盒子取1个,不就把这a个取出来了吗。
这种就等价于c个球放入a个盒子,允许有空了
当1,2数目相同时:
// 1 2 1 2
//4 3 4 3 4
// 2 1 2 1
//3 4 3 4 3
要么3多一个,要么4多一个,两种情况加起来即可,同上做法。
代码:
注意阶乘要开到2e6,因为c虽然最大为1e6,但是我们先欠做法计算的是c + gap
ll a[2000005];
ll ksm(int x, int y, int mod) {
if (x == 1) return 1;
ll res = 1, base = x;
while (y) {
if (y & 1) res = (res * base) % mod;
base = (base * base) % mod;
y >>= 1;
}
return res;
}
ll C(ll n, ll m, ll p)
{
if (m > n)return 0;
return ((a[n] * ksm(a[m], p - 2, p)) % p * ksm(a[n - m], p - 2, p) % p);
}
void solve()
{
int a, b, c, d;
cin >> a >> b >> c >> d;
if (abs(a - b) > 1 || a == 0 && b == 0 && c!=0&& d!=0)
{
cout << 0 << endl;
return;
}
if (a == 0&&b==0)
{
if (c == 0 || b == 0)
cout << 1 << endl;
else
cout << 0 << endl;
return;
}
//
int ans = 0;
int gap = max(a, b);
if (a == b)
{
ans = (C(c + gap, gap, mod) * C(d + gap - 1, gap - 1, mod) % mod
+ C(c + gap - 1, gap - 1, mod) * C(d + gap, gap, mod) % mod)%mod;
}
else
{
ans = C(c + gap - 1, gap-1, mod) * C(d + gap - 1, gap-1, mod) % mod;
}
cout << ans << endl;
}
signed main()
{
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
a[0] = a[1] = 1;
for (int i = 2; i <= 2000000; i++)
{
a[i] = a[i - 1] * i%mod;
}
int t = 1;
cin >> t;
while (t--)
{
solve();
}
return 0;
}