CSU 1320:Scoop water(卡特兰数)

http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1320

题意:……是舀的时候里面必须要有1L,而不是舀完必须要有1L。

思路:才知道是卡特兰数。

这个感觉写的很好 http://www.cnblogs.com/wuyuegb2312/p/3016878.html

卡特兰数可以解决:求括号匹配,出栈入栈等组合个数的问题。

卡特兰数公式:
first O(n): h(n) = h(n-1) * (4*n-2) / (n+1)
second O(n^2): h(n) = h(0)*h(n-1) + h(1)*h(n-2) …… + h(n-1)*h(0)

third 直接算的公式:h(2n) = C(n, 2n) / (n+1)

第一种计算要用到逆元
逆元: 费马小定理
a^(m-1) ≡ 1(mod m)
a * a^(m-2) ≡ 1(mod m)
a^(m-2) ≡ (1/a)(mod m)

 1 #include <cstdio>
 2 using namespace std;
 3 typedef long long LL;
 4 #define N 10010
 5 #define MOD 1000000007
 6 LL f[N];
 7 /*
 8 卡特兰数公式:
 9 first O(n): h(n) = h(n-1) * (4*n-2) / (n+1)
10 second O(n^2): h(n) = h(0)*h(n-1) + h(1)*h(n-2) …… + h(n-1)*h(0)
11 逆元: 费马小定理
12 a^(m-1) ≡ 1(mod m)
13 a * a^(m-2) ≡ 1(mod m)
14 a^(m-2) ≡ (1/a)(mod m)
15 */
16 LL q_pow(LL a, LL b) {
17     LL ans = 1;
18     a %= MOD; b %= MOD;
19     while(b) {
20         if(b & 1) ans = (ans * a) % MOD;
21         b >>= 1;
22         a = (a * a) % MOD;
23     }
24     return ans;
25 }
26 // 快速乘(貌似鸡肋)
27 LL q_mul(LL a, LL b) {
28     LL ans = 0;
29     a %= MOD;
30     while(b) {
31         if(b & 1) {ans = (ans + a) % MOD; b--;}
32         b >>= 1;
33         a = (a + a) % MOD;
34     }
35     return ans % MOD;
36 }
37 
38 void dabiao() {
39     f[0] = f[1] = 1LL;
40     for(int i = 2; i <= 10000; i++) // first
41         f[i] = f[i-1] * (4 * i - 2) % MOD * q_pow(i + 1, MOD - 2) % MOD;
42 //    for(int i = 2; i <= 10000; i++) second
43 //        for(int j = 0; j < i; j++)
44 //            f[i] = (f[i] + f[i-j-1] * f[j] % MOD) % MOD;
45 }
46 
47 int main() {
48     int n; dabiao();
49     while(~scanf("%d", &n)) printf("%lld
", f[n] % MOD);
50     return 0;
51 }
原文地址:https://www.cnblogs.com/fightfordream/p/6305688.html