题目描述


基准时间限制:1 秒 空间限制:131072 KB 分值: 10 难度:2级算法题 收藏 关注
M * N的方格,一个机器人从左上走到右下,只能向右或向下走。有多少种不同的走法?由于方法数量可能很大,只需要输出Mod 10^9 + 7的结果。
Input
第1行,2个数M,N,中间用空格隔开。(2 <= m,n <= 1000000)
Output
输出走法的数量 Mod 10^9 + 7。
Input示例
2 3
Output示例
3


解题思想


/**
本题的主要思想还是求乘法逆元。
用的方法是欧拉定理(费马小定理)+快速幂 = 逆元
欧拉定理:如果俩个数a,b互质,则a^φ(b) ≡ 1(mod) b
如果b也是质数,则φ(b)=b-1;
又因为本题是求C(m+n-2,n-1) = (m+n-2)! / ((n-1)!*(m-1)!)
设a=(m+n-2)!
b = (n-1)!*(m-1)!
p = 1e9+7
result = a/b % p
因为ab是求阶乘,求的过程肯定要%p,
所以原式=(a%p) / (b%p) % p
但是这样求是不对的. 因为 (a%p) / (b%p) %p 不等于 (a/b) % p
但是(a*b) % p = (a%p) * (b%p) %p
所以需要求逆元,将除法转换成乘法
上面是为什么要用逆元,下面是为什么可以用欧拉定理+快速幂求逆元.
解:根据欧拉定理:如果俩个数a,b互质,则a^φ(b) ≡ 1(mod) b
因为result = a/b % p
因为p是质数,所以pb互质(质数和其他数都互质),
所以b^φ(p)  % p =1
又如果b也是质数,则φ(b)=b-1;
所以原式等于b^(p-1) % p =1
也等于b * b^(p-2) % p =1
result = a /b *(1) % p = a/b *(b * b^(p-2)) % p = a * b^(p-2) %p
所以最终结果就变成了求b的(p-2)次幂,用快速幂求就好。
全部解题思路完毕。

*/

代码


import java.util.Scanner;
public class Main{
    static final int p = 1000000007;
    static final int max = 1000005;
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        int M = sc.nextInt();
        int N = sc.nextInt();
        //init
        long[] fc = new long[max*2];
        //阶乘打表 
        fc[0] = 1;
        fc[1] = 1;
        for(int i=2; i<max*2; ++i)
            fc[i] = (fc[i-1]*i)%p;
        //求b^(M-2)
        long ans = (quick_pow(fc[N-1],p-2) * quick_pow(fc[M-1], p-2)) % p;
        System.out.println((fc[M+N-2]*ans) % p);
    } 
    //快速幂模板
    public static long quick_pow(long b, long n){
        long ans = 1;
        while(n > 0){
            if((n&1) == 1)
                ans = ans*b%p;
            n >>= 1;
            b = b*b%p;
        }
        return (ans+p)%p;
    }
}