The Uncountable WaysProblem code: CNTWAYS |
All submissions for this problem are available.
Little Chef loves mathematics. Every day, he solves some mathematical problems to improve his skill.
Little Chef loves mathematics.Every day, he solves some mathematical problems to improve his skill.
A few days ago, he found a popular problem about turtles. The problem is as follows. Little Chef is givenR rectangles, numbered 1 through R. The width and height of the i-th rectangle are Ni and Mi unit respectively. There is a turtle located on the top-left corner of each rectangle. For each rectangle, count the number of ways the turtle can reach the bottom-right corner, if each turtle can only move right or down 1 unit at any time.The turtle is not allowed to move outside the rectangle, but, of course, the turtle can move on the boundary of the rectangle.
In less than one second, this problem was solved for all rectangles.He felt that the problem was too easy. This morning, Little Chef wanted more challenges. Thus, for each rectangle i, he cut and removed a rectangle of Ai × Bi unit from the top-right corner. See the following figure for detail.
He could not solve this new version of the problem easily. Help him count the number of ways each turtle can reach the bottom-right corner using the same rule as before.
Input
The first line of the input contains a single integer R. The description of R rectangles follows. Each description consists of a single line containing four space-separated integers Ni, Mi, Ai, and Bi.
Output
For each rectangle, output a single line containing the number of ways, modulo 1,000,000,007.
Constraints
1 ≤ R ≤ 10
2 ≤ Ni, Mi ≤ 400,000
1 ≤ Ai < Ni
1 ≤ Bi < Mi
Example
Input: 1 2 2 1 1 Output: 5
Explanations:
In the sample case, there are 5 ways the turtle can reach the bottom right corner as follows:
思路:
一个大矩形挖去一个小矩形后走法可以看成是要走多组对角相邻的两个矩形;
如题中图的意思,可先走到(N-A , B)的位置,再由该位置走到右下角,这是一组对角相邻的矩形;
第二组对角的相邻位置为(N-A-1 ,B+1)实际上这是上个相邻点在一个单元格里的的对角点,找出所有这些往左下角走的点即可;
相当于初始点为(N-A , B),有C(N-A+B , B)*C(M-B+A , M-B)种方法走完第一种情况,然后A++,B++,再计算第二组数据,依次类推,
但可以发现,当A++,B++ 时C(N-A+B , B)只有右边的增1 而左边的值不变,C(M-B+A , M-B)也类似,只有右边减1;这样用公式C(N,R)=(N-R+1)/R*C(N, R-1)即可求;
(赛期已过,以下代码并没有提交,只是一个想法)
#include<stdio.h>
#include<iostream>
typedef long long ll ;
using namespace std;
const ll M = 1000000007;
ll num1[800000];
ll num2[800000];
int main()
{
ll r,a1,b1,m1,n1,a,b,c,d,s,i,k1,k2;
scanf("%lld",&r);
while(r--)
{
s=0;k1=0;k2=0;
scanf("%lld%lld%lld%lld",&a,&b,&c,&d);
a1=a-c+d;
b1=d;
m1=c+b-d;
n1=b-d;
num1[k1]=1;i=a1;
while(i!=b1)
{
num1[k1+1]=(num1[k1]*i/(a1-i+1))%M;
k1++;i--;
}
num2[k2]=1;i=0;
while(i!=n1)
{
i++;
num2[k2+1]=(num2[k2]*(m1-i+1)/i)%M;
k2++;
}
for(;d<=b&&c<=a;d++,c++)
s=(s+num1[k1--]*num2[k2--]%M)%M;
printf("%lld\n",s);
}
return 0;
}