度度熊最近很喜欢玩游戏。这一天他在纸上画了一个2行N列的长方形格子。他想把1到2N这些数依次放进去,但是为了使格子看起来优美,他想找到使每行每列都递增的方案。不过画了很久,他发现方案数实在是太多了。度度熊想知道,有多少种放数字的方法能满足上面的条件?
第一行为数据组数T(1<=T<=100000)。
然后T行,每行为一个数N(1<=N<=1000000)表示长方形的大小。
对于每组数据,输出符合题意的方案数。由于数字可能非常大,你只需要把最后的结果对1000000007取模即可。
2
1
3
Case #1:
1
Case #2:
5
对于第二组样例,共5种方案,具体方案为:
卡特兰数列。
KaTeX parse error: \tag works only in display equations
因为本题数据有点大且需要取模,所以在递推中需要使用逆元
设 ( n + 1 ) × x ≡ 1 ( m o d ( 1 e 9 + 7 ) ) (n+1)\times x\equiv 1(mod (1e9+7)) (n+1)×x≡1(mod(1e9+7))
∴ C a t a l a n ( n ) = C a t a l a n ( n − 1 ) × ( 4 × n − 2 ) × x \therefore Catalan(n)=Catalan(n-1)\times (4\times n-2)\times x ∴Catalan(n)=Catalan(n−1)×(4×n−2)×x
加上取模即可。
#include
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
#define pb push_back
#define mp make_pair
#define lowbit(x) (x&(-x))
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> PII;
typedef pair<double,double> PDD;
typedef pair<ll,ll> PLL;
const int INF = 0x3f3f3f3f;
const int maxn = 1e6 + 5;
const int mod = 1e9 + 7;
const double eps = 1e-8;
const double pi = asin(1.0) * 2;
const double e = 2.718281828459;
bool Finish_read;
template<class T>inline void read(T &x) {
Finish_read = 0;
x = 0;
int f = 1;
char ch = getchar();
while (!isdigit(ch)) {
if (ch == '-') {
f = -1;
}
if (ch == EOF) {
return;
}
ch = getchar();
}
while (isdigit(ch)) {
x = x * 10 + ch - '0';
ch = getchar();
}
x *= f;
Finish_read = 1;
};
int main(int argc, char *argv[]) {
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
#endif
ll *inv = new ll[maxn];
inv[1] = 1;
for (int i = 2; i < maxn; ++i) {
inv[i] = (mod - mod / i) * inv[mod % i] % mod;
}
ll *Catalan = new ll[maxn];
Catalan[1] = 1;
for (int i = 2; i < maxn - 1; ++i) {
Catalan[i] = Catalan[i - 1] * (4 * i - 2) % mod * inv[i + 1] % mod;
}
ll T;
read(T);
for (ll Case = 1, n; Case <= T; ++Case) {
read(n);
printf("Case #%lld:\n", Case);
printf("%lld\n", Catalan[n]);
}
#ifndef ONLINE_JUDGE
fclose(stdin);
fclose(stdout);
system("gedit out.txt");
#endif
return 0;
}