描述
小雪与小可可吵架了,他们决定以后互相再也不理对方了。尤其是,他们希望以后上学的路上不会再相遇。
我们将他们所在城市的道路网视作无限大的正交网格图,每一个整数点 (x,y) 对应了一个路口,相邻两个整数点之间有一条平行于 x 轴或平行于 y 轴的道路,其道路长度为 1。已经知道小雪家住在 (x_1,0) 处的路口附近,小可可的家住在 (x_2,0) 处的路口附近。另外我们还知道,小雪的学校在 (0,y_1) 处的路口附近,小可可的学校在 (0,y_2) 处的路口附近。其中保证 x_1 < x_2 且 y_1 < y_2。
因为上学不能迟到,所以小雪和小可可总是希望可以走最短路径去上学。同时为了避免见面,希望他们所选择的路线可以没有交点。
格式
输入格式
输入的第一行输入四个正整数,依次为 x_1, x_2, y_1, y_2,满足 x_1 < x_2 且 y_1 < y_2。
输出格式
在输出中,输出一个非负整数,表示可行方案的总数 ans 关于常数 10^9+7 取余后的值。
限制
对于30%的数据,0 < x_1,x_2,y_1,y_2<=500。
对于70%的数据,0 < x_1,x_2,y_1,y_2<=3000。
对于100%的数据,0 < x_1,x_2,y_1,y_2<=100000。
提示
对于样例一来说,一共有三种可行方案,如下图所示。
图丢了>_<
来源
AHOI 2015
首先,从 (x, 0) 到 (0, y) 的最短路,一定是只能向左走和向上走,那么用组合数算一下方案数是 C(x + y, x), 其实就是将 y 次向上走分配到 x + 1 个横坐标上有几种情况。主要考虑组合数学的计算方法。
#include<stdio.h>
#include<string.h>
#include<algorithm>
#define LL long long
const int MaxN=200000+5,Mod = 1000000007,MN=200000;
int x,y,xx,yy;
LL Ans;
LL Fac[MaxN];
void PP()
{
Fac[0]=1;
for(int i=1;i<=MN;i++)
{
Fac[i]=Fac[i-1]*(LL)i%Mod;//将阶乘的结果先保存
}
}
LL Pow(LL a,int b)
{
LL ret=1,f=a;
while(b)
{
if(b&1)
{
ret*=f;
ret%=Mod;
}
b>>=1;
f*=f;
f%=Mod;
}
return ret;
}
inline LL Inv(LL x)
{
return Pow(x,Mod-2);
}
LL C(int x,int y)
{
return Fac[x]*Inv(Fac[y])%Mod*Inv(Fac[x-y])%Mod;
}
LL solve(int x,int y)
{
return C(x+y,x);
}
int main()
{
PP();
scanf("%d%d%d%d",&x,&xx,&y,&yy);
Ans=(solve(x,y)*solve(xx,yy)%Mod-solve(x,yy)*solve(xx,y)%Mod)%Mod;
Ans=(Ans+Mod)%Mod;
printf("%lld\n",Ans);
}