hdu 5698(杨辉三角的性质+逆元)

---恢复内容开始---

瞬间移动

Accepts: 1018
Submissions: 3620
Time Limit: 4000/2000 MS (Java/Others)
Memory Limit: 65536/65536 K (Java/Others)
Problem Description

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

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

Input

多组测试数据。

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

Output

一个整数表示答案

Sample Input
4 5
Sample Output
10

注:本文中 C(n,m) 代表了在n个数中取m个数的组合数.
题解:这个题写出前几项之后就应该能够看出是个斜过来的杨辉三角了,杨辉三角的第i行之和为 2^i ,而 2^i又对应了一个二项式展开的系数之和 ,比如 2^n = C(n,1)+C(n,2)+...C(n,n)..然后对应到
我们的图中(见下图),我们会发现行为n,列为m 对应了 2^(n+m-4)这一行,所以我们就可以知道我们要求的点对应的是杨辉三角第 n+m-4 行(这里是从0开始计数),然后根据下图我们也可以得到第我们要求
的第n行是杨辉三角中的第 n-2 行,所以我们可知道 d = (n+m-2)-(n-2) = m-2 ,所以所求结果为第 n+m-4 行中的第 m+2 个数 ,结果自然就是 C(n+m-4,n-2)
然后我们就能 知道 ans = ((n+m-4)!/((n-2)!*(m-2)!))%1000000007 我们可以先打表将所有的阶乘(n+m<2*10^5)求出来,然后求出 (n-2)!*(m-2)!的逆元 inv,结果就为
((n+m-4)!*inv)%1000000007

AC代码:
#include <stdio.h>
#include <math.h>
#include <iostream>
#include <algorithm>
#include <string.h>
#include <stdlib.h>
using namespace std;
typedef long long LL;
const int mod = 1000000007;
const int N = 200005;
char str[N];
LL f[N];
LL extend_gcd(LL a,LL b,LL &x,LL &y){
    if( b == 0 ) {
        x = 1;
        y = 0;
        return a;
    }
    else{
        LL x1,y1;
        LL d = extend_gcd(b,a%b,x1,y1);
        x = y1;
        y= x1-a/b*y1;
        return d;
    }
}
LL mod_reverse(LL a,LL n)
{
    LL x,y;
    LL d=extend_gcd(a,n,x,y);
    if(d==1) return (x%n+n)%n;
    else return -1;
}
void init(){
    f[0]=1,f[1] = 1;
    for(int i=2;i<=N;i++){
        f[i] = (f[i-1]*i)%mod;
    }
}
int main()
{
    int n,m;
    init();
    while(~scanf("%d%d",&n,&m)){
        LL t = f[n-2]*f[m-2];
        LL inv = mod_reverse(t,mod);
        LL ans = (f[n+m-4]*inv)%mod;
        printf("%d\n",ans);
    }
}

 


---恢复内容结束---

posted @ 2016-05-23 11:00  樱花庄的龙之介大人  阅读(346)  评论(0编辑  收藏  举报