F - Grids
度度熊最近很喜欢玩游戏。这一天他在纸上画了一个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种方案,具体方案为:
本题表示
需要把最后的结果对1000000007取模即可。对答案取模,在计算过程中就进行避免答案过大溢出。
1.扩展欧几里德算法
2.求逆元
3.卡特兰数
//推导公式:h(n)=h(n-1)*(4*n-2)/(n+1);
//因为有取模,所以可以用long long 不会超限
#include <cstdio>
#include <cstring>
using namespace std;
const int N = 1000005;
const long long MOD = 1000000007;
long long extend_gcd(long long a,long long b,long long &x,long long &y)
{
if(a == 0 && b == 0) return -1;
if(b == 0){
x = 1; y = 0;
return a;
}
long long d = extend_gcd(b, a % b, y, x);
y -= a / b * x;
return d;
}
long long mod_reverse(long long a, long long n) //求逆元
{
long long x,y;
long long d = extend_gcd(a, n, x, y);
if(d == 1) return (x % n + n) % n;
else return -1;
}
long long C[N];
int main() {
C[1] =1; C[2] = 1;
for (int i = 2; i < N; i++) {
long long tmp = mod_reverse((long long) i, MOD);
C[i] = C[i - 1] * (4 * i - 6) % MOD * tmp % MOD; //除法取模
}
int ans = 1,t,n;
scanf("%d", &t);
while (t--){
scanf("%d", &n);
printf("Case #%d:\n", ans++);
printf("%lld\n", C[n+1]);
}
return 0;
}