首页 > 移动平台 > 详细

HDU 5698 瞬间移动

时间:2016-08-21 11:08:14      阅读:227      评论:0      收藏:0      [点我收藏+]

题目:

Description

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

Input

多组测试数据。 

两个整数技术分享技术分享技术分享技术分享技术分享技术分享技术分享技术分享技术分享技术分享技术分享技术分享技术分享技术分享技术分享技术分享技术分享 

Output

一个整数表示答案

Sample Input

4 5

Sample Output

10


首先,很容易求出答案是(m+n-4)!/(m-2)!/(n-2)!
然后就是想办法打表了。
肯定不是真的把阶乘都存起来,因为10000!的十进制有35660位,100000!的位数就更是多的多。
既然这个题目是模1000000007的,那么阶乘也是可以用模1000000007来存的。
最后只剩下1个问题,在模运算下,如何计算除法。
数论里面有个专门解决除法的好东西,叫逆元。
根据费马小定理,用快速幂就可以求出逆元。

代码:

#include<iostream>
using namespace std;

int p = 1000000007;
long long fac[200000];
long long anti[100000];

long long get_mi(long long n,int k)
{
	if (k == 0)return 1;
	long long r = get_mi(n, k / 2) % p;
	r = (r*r) % p;
	if (k % 2)r = (r*n) % p;
	return r;
}

void build()
{
	fac[0] = 1;
	anti[0] = 1;
	for (int i = 1; i < 100000; i++)
	{
		fac[i] = (fac[i - 1] * i) % p;
		anti[i] = get_mi(fac[i], p - 2);	//费马
	}
	for (int i = 100000; i <200000; i++)fac[i] = (fac[i - 1] * i) % p;
}

int main()
{
	build();
	int n, m;
	while (cin >> n >> m)
	{
		long long r = fac[m + n - 4];
		r = (r*anti[m - 2]) % p;
		r = (r*anti[n - 2]) % p;
		cout << r << endl;
	}
	return 0;
}


HDU 5698 瞬间移动

原文:http://blog.csdn.net/nameofcsdn/article/details/52265907

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!