acdream 1040: whxnwjq got the champion 卡特兰数

题目大意:

  给出递推公式,求   % 1e9+7

   

    

 

看大神们的思路:除1外,奇数全为0,对于偶数2k,答案为(-1)^k*fact[2k]*catalan(k+1)。p[i]表示i的阶乘。

表示弱菜依旧无法理解哪里看出来的规律,哪怕是 catalan(n) 为 阶乘倍数的关系知道我也没弄出来...求大神普渡~~~

 

AC代码:

View Code
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<algorithm>
using namespace std;
typedef long long LL;
const int N = 1e7+7;
const int mod = 1e9+7;

LL fact[N];
int n;
LL mult( LL a, LL b)
{
    LL res = 0;
    while( b ){
        if(b&1) if( (res+=a) >= mod ) res -= mod;
        a <<= 1; if( a >= mod ) a -= mod;
        b >>= 1;
    }
    return res;
}

LL ExGcd( LL a, LL b, LL &x, LL &y)
{
    if( b == 0 ){    x = 1; y = 0; return a; }
    LL r = ExGcd( b, a%b, x, y );
    LL t = x;
    x = y; y = t - (a/b)*y;
    return r;
}
LL inverse( LL A ){ //求逆元,简化计算
    LL a = A, b = mod, x, y;
    ExGcd( a, b, x, y );
    return (x%mod+mod)%mod;
}
LL catalan( int x ){
    LL A = inverse( fact[x] ) , B = inverse(x+1); // H(n) = (2n!)*A*A*B
    return mult( mult( fact[x<<1], B ) , mult( A, A)  );
}
void init(){
    fact[0] = 1;
    for(LL i = 1; i <= N; i++)
        fact[i] = fact[i-1]*i%mod;
}
int main(){
    init();    
    while( scanf("%d", &n) != EOF)
    {
        if( n == 1 ) puts("1");
        else if( n&1 ) puts("0");
        else{    
            n /= 2;
            LL ans = 1;
            if( n%2 == 1 ) ans = mod-1;
            //LL ans = mult( fact[n], catalan( n/2 + 1 ) );    
            printf("%lld\n", mult(ans, mult(fact[2*n],catalan(n-1) ) ) );    
        }
    }
    return 0;
}

 

posted @ 2012-12-26 17:59  yefeng1627  阅读(188)  评论(0编辑  收藏  举报

Launch CodeCogs Equation Editor