【HDU 5698】 瞬间移动

【题目链接】

           点击打开链接

【算法】

          用f[i][j]表示走到(i,j)这个位置有多少种方案,因为走到(i,j)这个位置,上一步一定在它左上角的矩形中,所以,

          f(i,j) = sigma( f(x,y) ) ( (x,y)在左上角的矩形中) 

          我们尝试将它画出来,发现是斜着的杨辉三角

          然后,通过找规律,我们发现 : f(n,m) = C(n+m-4,n-2) 

          求C函数的值,这里有一种方法 :

           C(n,r) mod P = (n! / (n - r)! / r!) mod P

                                = (n!) mod P * inv( (n - r)! ) mod P * inv( r! ) mod P( 其中,inv表示乘法逆元 )

           考虑预处理阶乘和阶乘逆元

           阶乘很容易求,那么,阶乘逆元怎么求呢?

           这里有一种线性求阶乘逆元的方法 ( 如果我们要求 inv( n! ) ) :

           inv(n ! ) = inv( (n - 1)! n )

                        = inv( (n - 1)! ) inv( n )

           所以 inv( (n - 1)! ) = inv( n ! ) * inv( inv( n ) )

                                        = inv( n! ) * n

           有了这个式子,我们便可以在线性时间内求出所有的阶乘逆元

           这一题,我们只要预处理阶乘和阶乘逆元,然后,O(1)回答询问,即可

【代码】

           

#include<bits/stdc++.h>
using namespace std;
#define MAXN 200010
const long long P = 1000000007;

long long n,m;
long long fac[MAXN],inv[MAXN];

inline long long power(long long a,long long n)
{
        long long ans = 1,b = a;
        while (n > 0)
        {
                if (n & 1) ans = (ans * b) % P;
                b = (b * b) % P;
                n >>= 1;
        }
        return ans;
}
inline void init()
{
        int i;
        fac[0] = 1;
        for (i = 1; i < MAXN; i++) fac[i] = fac[i-1] * i % P;
        inv[MAXN-1] = power(fac[MAXN-1],P-2);
        for (i = MAXN - 2; i >= 1; i--) inv[i] = inv[i+1] * (i + 1) % P;
}
inline long long C(long long n,long long m)
{
        if (!m) return 1;
        else if (n == m) return 1;
        else return fac[n] * inv[n-m] % P * inv[m] % P;    
}

int main() {
        
        init();
        while (scanf("%d%d",&n,&m) != EOF)
        {
                printf("%lld\n",C(n+m-4,n-2));    
        }
        
        return 0;
    
}

/*
  f( n! ) = f( (n-1)! n) = f( (n - 1)! ) f(n)
  f( n! ) * f( f(n) ) = f( (n - 1)! )
    f( n! ) * n = f( (n - 1)! )
    f( n! ) = f ( (n + 1)! ) * (n + 1)
*/ 

 

posted @ 2018-05-27 22:40  evenbao  阅读(121)  评论(0编辑  收藏  举报