【HDU - 5698】瞬间移动(求组合数)

有一个无限大的矩形,初始时你在左上角(即第一行第一列),每次你都可以选择一个右下方格子,并瞬移过去(如从下图中的红色格子能直接瞬移到蓝色格子),求到第nn行第mm列的格子有几种方案,答案对10000000071000000007取模。 

Input

多组测试数据。 

两个整数n,m(2≤n,m≤100000)n,m(2≤n,m≤100000) 

Output

一个整数表示答案

Sample Input

4 5

Sample Output

10

思路:(参考博客)

求1e5范围内的组合数,二维数组的打表方式肯定是不行的。所以这里用了组合数的阶乘求法的公式,求出1e5以内数的阶乘,然后求逆元最后相乘。这道题目需要注意预处理的范围是2e5,因为最后是求n+m-4的,注意特判一下n=2或m=2的情况。

对于这道题目,可以先写出前几项找规律,最后能发现斜着是个杨辉三角。

ac代码:

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define mod (1000000007)
using namespace std;
typedef long long ll;
const int N = 1e6 + 5;
ll f[N];//阶乘会爆int 
void init(int n, int p) {
    f[1]=1; 
	for(int i=2;i>=1;
		a=a*a%mod;
	}
	return t; 
}
int main()
{
	init(300000,mod);
	int n,m;
	while(~scanf("%d%d",&n,&m))
	{
		if(n==2||m==2) puts("1");
		else
		printf("%lld\n",1ll*f[n+m-4]*inv(f[n-2],mod)%mod*inv(f[m-2],mod)%mod); 
	}
	return 0;
}

 

你可能感兴趣的:(组合数,找规律,数学)