hdu-2848-Grids(卡特兰数)附费马小定理 ʕ •ᴥ•ʔ

Grids

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)
Total Submission(s): 394    Accepted Submission(s): 151


 

Problem Description

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

Input

  第一行为数据组数T(1<=T<=100000)。
  然后T行,每行为一个数N(1<=N<=1000000)表示长方形的大小。

Output

  对于每组数据,输出符合题意的方案数。由于数字可能非常大,你只需要把最后的结果对1000000007取模即可。

Sample Input

 

2 1 3

Sample Output

 

Case #1: 1 Case #2: 5

Hint

对于第二组样例,共5种方案,具体方案为:

Source

2014年百度之星程序设计大赛 - 初赛(第一轮)

Recommend

liuyiding   |   We have carefully selected several similar problems for you:  4871 4870 4869 4868 4867

推一下可以看出是 卡特兰数 1 2 5 14 ... 然后根据递推式f[n]=f[n-1]*(4n-2)/(n+1)

因为有除法 为了避免精度损失 我们需要用费马小定理转换一下,否在会爆精度

转换式

(a/b)%mod = (a/b)*1%mod = (a/b)*b^(mod-1)%mod = a*b^(mod-2)%mod;

记忆: /b =b^(mod-2)%mod

#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
using namespace std;
#define ll long long
#define mod 1000000007
#define N 4000010
// 卡特兰数1 2 5 14 42
// 公式:f(n)=f(n-1)*(4n-2)/(n+1) 
ll f[N];
ll power(ll a,ll b)
{
	ll ans=1;
	while(b)
	{
		if(b&1)
		ans=(ans*a)%mod;
		a=(a*a)%mod; 
		b>>=1;
	}
	return ans;
}
void di()
{
	f[1]=1;
	for(int i=2;i<1000010;i++)
	{
		f[i]=(f[i-1]*(4*i-2))%mod;
		f[i]=f[i]*power(i+1,mod-2)%mod;
	}
	
}
int main()
{
	di();
	int t;
	cin>>t;
	int z=1;
	while(t--)
	{
		int n;
		cin>>n;
		cout<<"Case #"<<z++<<":"<<endl<<f[n]%mod<<endl;
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/henucm/article/details/81664411