1.题目链接。题目大意:一个人从(0,y1)走到(x1,0),另一个人从(0,y2)走到(x2,0).求他们路线不相交的方案数。
2.。。。行吧,这个题推了快1h,因为智商底。。其实很好理解,首先,我们不考虑任何限制,从(0,y)走到(x,0)的方案数其实就是一个组合数C(x+y,x).然后在不考虑任何限制的时候:ans=C(x1+y1,x1)*C(x2+y2,x2).如果二者相交,那么只需要保持y不变,x互换,然后就是C(x1+y2,x1)*C(x2+y1,x2).二者之差就是答案。这当然是聚聚们的写法了,如果正常的想法是,我们枚举所有的交点。然后减去,其实最后发现求和之后就是上边的第二种情况,但是这个求和十分的复杂。。。。。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = 2e5+100;
const int mod = 1e9 + 7;
ll fac[maxn];
ll inv[maxn];
#pragma warning(disable:4996)
ll qpow(ll a, ll b, ll mod)
{
ll res = 1;
while (b)
{
if (b & 1)
res = res * a%mod;
a = a * a%mod;
b >>= 1;
}
return res;
}
void inv_ini()
{
fac[0] = 1;
for (int i = 1; i < maxn; i++)
{
fac[i] = fac[i - 1] * i%mod;
}
inv[maxn - 1] = qpow(fac[maxn - 1], mod - 2, mod);
for (int i = maxn - 2; i >= 0; i--)
{
inv[i] = inv[i + 1] * (i + 1) % mod;
}
}
ll C(ll n, ll m)
{
ll ans = fac[n] * inv[m] % mod*inv[n - m] % mod;
return ans;
}
int main()
{
int T;
cin >> T;
inv_ini();
while (T--)
{
ll x1, x2, y1, y2;
scanf("%lld%lld%lld%lld", &x1, &x2, &y1, &y2);
ll ans = (C(x1 + y1, x1)*C(x2 + y2, x2)%mod - C(x1 + y2, x1)*C(x2 + y1, x2)%mod + mod) % mod;
printf("%lld\n", ans);
}
}