A Path Plan
题解
很容易发现,如果两个起点与终点的连线相交时,即时,无论怎么走都是一定会相交的。因此我们只需考虑
的情况。
不妨设,如果会相交的话,路径一定是这样的
两者一定会相交于一个点,我们尝试将它们的终点互换一下,就成了这样
可以发现,任意一条会相交的路径相当于从的合法方案数。
于是答案就是从。
源码
#include<cstdio>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<map>
#include<set>
using namespace std;
#define MAXN 200005
typedef long long LL;
const int mo=1e9+7;
#define gc() getchar()
template<typename _T>
void read(_T &x){
_T f=1;x=0;char s=gc();
while(s>'9'||s<'0'){if(s=='-')f=-1;s=gc();}
while(s>='0'&&s<='9'){x=(x<<3)+(x<<1)+(s^48);s=gc();}
x*=f;
}
int fac[MAXN],inv[MAXN],f[MAXN];
void init(){
fac[0]=inv[0]=fac[1]=inv[1]=f[1]=1;
for(int i=2;i<=2e5;i++){
fac[i]=1ll*fac[i-1]*i%mo;
f[i]=1ll*(mo-mo/i)*f[mo%i]%mo;
inv[i]=1ll*inv[i-1]*f[i]%mo;
}
}
int C(int x,int y){
if(x<0||y<0||x<y)return 0;
return 1ll*fac[x]*inv[y]%mo*inv[x-y]%mo;
}
int main(){
int t;read(t);init();
while(t--){
int x1,x2,y1,y2;
read(x1);read(x2);read(y1);read(y2);
if(x1>x2)swap(x1,x2),swap(y1,y2);
if(y1>y2)puts("0");
else printf("%d\n",(mo+1ll*C(x1+y1,x1)*C(x2+y2,x2)%mo-1ll*C(x1+y2,x1)*C(x2+y1,x2)%mo)%mo);
}
return 0;
}