Hdu 5698 瞬间移动【组合+逆元】


瞬间移动

Problem Description

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

http://acm.hdu.edu.cn/data/images/C702-1003-1.jpg

Input

多组测试数据。

两个整数n,m(2\leq n,m\leq 100000)n,m(2n,m100000)

Output

一个整数表示答案

Sample Input
4 5
Sample Output
10

Source

2016"百度之星" - 初赛(Astar Round2B) 


题意:

手动尝试几组数据,会发现其实就是杨辉三角,也就是组合问题,

不过在求解的时候,涉及到除法运算,求模运算不支持除法,因此用逆元进行处理....

求n的组合数(第n行的杨辉三角数)的递推式为:


c[0]=1;

c[i]=c[i-1]*(n-i+1)/i  (1<=i<=n)


/*
http://blog.csdn.net/liuke19950717
*/
#include
#include
#include
using namespace std;
typedef long long ll;
const ll maxn=1000005;
const ll mod=1000000007;
ll x[maxn];
void extgcd(ll a,ll b,ll &x, ll &y)
{
    if(!b)
    {
        x=1;y=0;
        return;
    }
    extgcd(b,a%b,y,x);
    y-=(a/b)*x;
}
ll inv(ll a,ll n)
{
    ll x,y;
    extgcd(a,n,x,y);
    return (x+n)%n;
}
int main()
{
    ll n,m;
    while(~scanf("%lld%lld",&n,&m))
    {
        memset(x,0,sizeof(x));
        ll s=n+m-4;
        x[0]=1;
        for(ll i=1;i<=s;++i)
        {
        	x[i]=(x[i-1]*(s-i+1))%mod;
        	x[i]=(x[i]*inv(i,mod))%mod;
        }
        printf("%I64d\n",x[m-2]);
    }
    return 0;
}



你可能感兴趣的:(组合数学,hdu,oj,数论)