0
点赞
收藏
分享

微信扫一扫

HDU - 4828 Grids

洲行 2023-03-02 阅读 48


 度度熊最近很喜欢玩游戏。这一天他在纸上画了一个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;
}

 

举报

相关推荐

0 条评论