题意: 链接:https://www.nowcoder.com/acm/contest/96/J
一天durong同学买了一个无限长的杯子,同时买了n个球,并且标号为1,2,3......n,durong同学突然想到一个问题----如果他把n个球依次,
也就是按照1,2,3...n的顺序放进杯子里,然后在全部拿出来(注意不一定要等到全部放进去才能拿出球),并且会记录放进和拿出球的顺序,
durong想知道,要满足当第m个球进去后,杯子中此时恰好有k个球,然后仍然要把剩下的n-m个球放进去,最后杯中的球要取光,
这样的放进和拿出球的顺序有多少种,答案有可能很大,所以mod上1e9+7。
对于n个0,m个1 的任意前缀0的个数不小于1的种数是 C(n+m,n)-C(n+m,m-1)。
卡特兰数是n = m 的特殊情况, 通项公式为 C(2 * n, n) / (n + 1)
1 #include<bits/stdc++.h> 2 #define LL long long 3 #define fi first 4 #define se second 5 #define mk make_pair 6 #define pii pair<int,int> 7 using namespace std; 8 9 const int N=2e6+7; 10 const int M=1e4+7; 11 const int inf=0x3f3f3f3f; 12 const LL INF=0x3f3f3f3f3f3f3f3f; 13 const int mod=1e9 + 7; 14 15 int n, m, k; 16 LL f[N], inv[N]; 17 18 LL fastPow(LL a, LL b) { 19 LL ans = 1; 20 while(b) { 21 if(b & 1) ans = ans * a % mod; 22 a = a * a % mod; b >>= 1; 23 } 24 return ans; 25 } 26 void init() { 27 f[0] = 1; 28 for(int i = 1; i < N; i++) { 29 f[i] = f[i - 1] * i % mod; 30 } 31 for(int i = N - 1; i >= 0; i--) 32 inv[i] = fastPow(f[i], mod - 2); 33 34 } 35 36 LL C(int n, int m) { 37 if(n < m) return 0; 38 return f[n] * inv[m] % mod * inv[n - m] % mod; 39 } 40 41 LL getCatalan(int n, int m) { 42 return (C(n + m, n) - C(n + m, m - 1) + mod) % mod; 43 } 44 45 int main() { 46 init(); 47 int T; scanf("%d", &T); 48 while(T--) { 49 scanf("%d%d%d", &n, &m, &k); 50 if(m > n || k > m) { 51 puts("0"); 52 continue; 53 } 54 LL ret1 = getCatalan(m - 1, m - k); 55 LL ret2 = getCatalan(n - (m - k), n - m); 56 printf("%lld ", ret1 * ret2 % mod); 57 } 58 return 0; 59 } 60 /* 61 */