度度熊最近很喜欢玩游戏。这一天他在纸上画了一个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种方案,具体方案为:
卡特兰数
公式:Cn=Cn-1 * ((4*n-2)/(n+1))(不止这一个)
数太大。结合逆元
为什么要利用逆元呢?
在MOD的情况下, (a*b/c ) %MOD 不能直接 / c 来求,需要找到一个数 inv 使得 inv * c % MOD = 1 。 这样 (a*b / c) % MOD = (a * b * inv) % MOD;
然后套用公式,
/*
Cn=Cn-1 * ((4*n-2)/(n+1))
*/
#include <iostream>
#include <cstring>
#include <algorithm>
#include <string>
#include <algorithm>
#include <stack>
using namespace std;
#define ll long long
#define maxn 1000005
#define mod 1000000007
ll ans[maxn],t;
int ex_gcd(int a,int b,int &x,int &y)
{//扩展欧几里得
if(b==0)
{
x=1;
y=0;
return a;
}
int ans=ex_gcd(b,a%b,x,y);
int temp=x;
x=y;
y=temp-a/b*y;
return ans;
}
int mod_inverse(int a,int m)
{
int x,y;
ex_gcd(a,m,x,y);
return (x%m+m)%m;
//如果直接求出来是一个负数,那么显然我们要把他转化成正数
}
void get_catalan()
{
ans[0]=1;
for(int i=1;i<=maxn;i++)
{
ans[i]=((4*i-2)*ans[i-1])%mod*mod_inverse(i+1,mod)%mod;
}
}
int main()
{
get_catalan();
int cnt=0;
cin>>t;
while(t--)
{
cnt++;
int n;
cin>>n;
cout<<"Case #"<<cnt<<":"<<endl;
cout<<ans[n]<<endl;
}return 0;
}