hdu 4828 - Grids

题目:汉语题,不用翻译了吧(⊙_⊙)。

           度度熊最近很喜欢玩游戏。这一天他在纸上画了一个2行N列的长方形格子。他想把1到2N这些数依次放进去,但是为了使格子看起来优美,他想找到使每行每列都递增的方案。不过画了很久,他发现方案数实在是太多了。度度熊想知道,有多少种放数字的方法能满足上面的条件?

分析:组合,计数,卡塔兰数,数论。结果是卡塔兰数。

           这里要计算第1000000个卡特兰数,这个数字十分巨大,第10000个就有几千位了。

           题目本来是 Catalan(n+1)= Catalan(n)*(4*n+2)/(n+2)(mod M);

           而我们无法计算除法的模,所以要全都保存,肯定TLE;

           这里利用费马小定理转化下:

           因为,b ^(M-1)= 1(mod M);

           所以有 a / b mod M = a * b ^(M-1)/ b mod M = a * b ^ (M-1)mod M;

           快速幂搞定。

说明:百度之星,错过了o(╯□╰)o(虽然赶上也不应定做出来什么╮(╯▽╰)╭)。

#include   
#include   
#include   
  
using namespace std;  
  
long long C[1000005] = {0LL};  

long long spow(long long x, int n)  
{  
    if (n == 1)   
        return x;  
    else {  
        long long v = spow(x, n/2);  
        if (n%2 == 0) return v*v%1000000007LL;
		else return v*v%1000000007LL*x%1000000007LL;
    }  
}
  
int main()  
{  
    C[1] = 1LL;  
    for (int i = 2 ; i < 1000001 ; ++ i) {  
        C[i] = C[i-1]*(4*i-2)%1000000007LL;   
        C[i] = C[i]*spow(i+1, 1000000005)%1000000007LL;
	}
	
    int n,m;  
    while (cin >> n)
    for (int i = 1 ; i <= n ; ++ i) {
		cin >> m;
		cout << "Case #" << i << ":" << endl;
        cout << C[m] << endl;
	}
    return 0;  
}


你可能感兴趣的:(图论,动态规划(DP),解题报告,数论)