hdu 4828 Grids Catalan数例题
Time Limit: 10000/5000 MS (Java/Others)
Memory Limit: 65535/65535 K (Java/Others)
##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
引用维基百科的解释:
Cn is the number of standard Young tableaux whose diagram is a 2-by-n rectangle. In other words, it is the number of ways the numbers 1, 2, …, 2n can be arranged in a 2-by-n rectangle so that each row and each column is increasing. As such, the formula can be derived as a special case of the hook-length formula.
- 除法取模运算、Catalan数计算依赖于不同的推导,分别有多种不同写法,分别有不同的时间复杂度表现。
/** * Apr 3, 2016 9:54:01 PM * PrjName: hdu4828 * @semprathlon */ import java.io.*; import java.util.*; public class Main { final static int maxn = 1000010, mod = 1000000007; static long inv[] = new long[maxn]; static long a[] = new long[maxn]; static long b[] = new long[maxn]; static long C[] = new long[maxn]; static long x, y; static void extgcd(long a, long b) { if (b == 0L) { x = 1L; y = 0L; return; } extgcd(b, a % b); long t = x; x = y; y = t - a / b * y; } static void get_inv(int maxn, long mod) { inv[1] = 1; for (int i = 2; i < maxn; i++) { // inv[i] = (mod - mod / i) * inv[(int) (mod % i)] % mod; inv[i] = (int) cal_inv(i, mod); } } static long cal_inv(long n, long mod) { extgcd(n, mod); return x < 0L ? (x + mod) % mod : x % mod; } static long pow_mod(long n, long m, long mod) { long res = 1L; n %= mod; while (m > 0L) { if ((m & 1L) > 0L) res = res * n % mod; n = n * n % mod; m >>= 1; } return res; } static long div_mod(long n, long m, long mod) { // return n * pow_mod(m, mod - 2, mod) % mod; // return n * pow_mod(m, phi(mod) - 1, mod) % mod; return n * inv[(int) m] % mod; } static void get_Catalan(int maxn) { a[1] = 2; b[1] = 1; C[1] = 1; for (int i = 2; i < maxn - 1; i++) { /* * a[i] = a[i - 1] * ((i << 1) - 1) % mod * (i << 1) % mod; a[i] = * div_mod(a[i], i, mod); a[i] = div_mod(a[i], i, mod); b[i] = b[i - * 1] * ((i << 1) - 1) % mod * (i << 1) % mod; b[i] = div_mod(b[i], * i + 1, mod); b[i] = div_mod(b[i], i - 1, mod); C[i] = a[i] - * b[i]; if (C[i] < 0) C[i] += mod; */ C[i] = C[i - 1] * ((i << 2) - 2) % mod; C[i] = div_mod(C[i], i + 1, mod); } } public static void main(String[] args) throws IOException { InputReader in = new InputReader(System.in); PrintWriter out = new PrintWriter(System.out); get_inv(maxn, mod); get_Catalan(maxn); int T = in.nextInt(), cas = 0; while (T-- > 0) { int n = in.nextInt(); out.println("Case #" + (++cas) + ":"); out.println(C[n]); } out.flush(); out.close(); } }