D. Dandelion, 吉比特杯,WHU校赛2019

D. Dandelion

time limit per test1.0 s
memory limit per test256 MB
inputstandard input
outputstandard output
"O dandelion, yellow as gold,

What do you do all day?"

"I just wait here in the tall green grass

Till the children come to play."

"O dandelion, yellow as gold,

What do you do all night?"

"I wait and wait till the cool dews fall

And my hair grows long and white."

"And what do you do when your hair is white

And the children come to play?"

"They take me up in their dimpled hands

And blow my hair away!"

Spring is here and the dandelion is blooming. There is a small dandelion seed taking off. It will float upwards when there is no wind, and when the wind blows up it will be blown to the right.

In other words, if a dandelion seed is currently at point (x,y), the next second it will only appear in either point (x,y+1) or point (x+1,y). All points (x,y) on the path must satisfy the constraint that x is less than y(i.e x<y.

Now, there is a dandelion seed at point (0,0), please find the number of ways(mod 109+7) to reach the point (m,n). 0<m<n≤100000.

Input

The first line has a integer T (T<10), it means the number of the case.

The following lines of input will be two integers: m and n.

Output

For each case, print an integer in a single line to represent the answer.

Example

inputCopy

3
3 4
4 5
999 1000

outputCopy

5
14
894965608

思路:
在一个格点阵列中,从 (0,0) 点走到( m, n) 点且不经过对角线 x = y 的方法数 (x < y): C(n + m−1,m)−C(n + m−1,m−1)。
在一个格点阵列中,从 (0,0) 点走到 (m, n) 点且不穿过对角线 x = y 的方法数 (x <= y): C(n + m,m)−C(n + m,m−1)。

这里用公式C(n + m−1,m)−C(n + m−1,m−1)。

此题n, m较大, 一般求组合数的方法不行,得用费马小定理求逆元
关于逆元与组合数看这篇博客


#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
#include<set>
#include<map>
#include<string>
#include<vector>
#include<stack>
using namespace std;
typedef long long ll;
const int maxn = 100000, mod = 1e9 + 7;
int fac[maxn * 2];

int pow_mod(int a, int b)
{
	int base = a, res = 1;
	while(b)
	{
		if(b & 1) res = (ll) res * base % mod;
		
			base = (ll) base * base % mod;
		b >>= 1;
	}

	return res;
}

int solve(int a, int b)    				//solve()函数求得从a个中取b个的组合数。
{
	int temp = (ll) fac[b] * fac[a - b] % mod;
	int re = (ll)fac[a] * pow_mod(temp, mod - 2) % mod;
	return re;
}

int main()
{
	ios::sync_with_stdio(false);
	int t;
	cin >> t;
	fac[0] = 1;
	for(int i = 1; i <= 200000; i++) fac[i] = (ll)i * fac[i - 1] % mod;
	while(t--)
	{
		int m, n;
		cin >> m >> n;
		cout << (solve(m + n - 1, m) - solve(m + n -1, m - 1) + mod) % mod << endl;
	}
}

猜你喜欢

转载自blog.csdn.net/qq_40212930/article/details/89075611