题目:
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; }
时间: 2024-10-20 03:06:36