链接:https://ac.nowcoder.com/acm/contest/11356/I
来源:牛客网
为了让大家不被卡题意,这里给出一句话题意:
已知一个没有深度限制的栈的入栈序列为 A_1, A_2, A_3, \cdots, A_NA
1
,A
2
,A
3
,⋯,A
N
,且 A_1A
1
不能第一个出栈。求合法的出栈序列个数。答案对 998244353998244353 取模。
输入描述:
第一行一个数 TT ,表示蛙蛙有 TT 组询问。
接下去 TT 行,每行一个正整数 NN, 表示目的地的个数(入栈元素个数)。
输出描述:
输出共 TT 行,每行一个答案,格式形如 ,具体可见样例。
答案可能较大,请对 998244353998244353 取模后输出。
示例1
输入
复制
3
3
9
24
输出
复制
Case #1: 3
Case #2: 3432
Case #3: 508887030
说明
对于样例中的第一个询问,设三个目的地为 AA, BB, CC,其中 AA 是第一个目的地,所以不能第一个访问。则有三种合法访问序列:
· B, A, CB,A,C
· B, C, AB,C,A
· C, B, AC,B,A
备注:
1 \leq T \leq 2001≤T≤200
1 \leq N \leq 10^51≤N≤10
5
A1 不能第一个出栈
所有的出栈顺序 为第N个卡特兰数
如果A1第一个出栈 那么所有的出栈顺序就是 第(N - 1)个卡特兰数
所以 所有可用的出战顺序 就是 H(N) - H (N - 1)
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
#define int long long
const int mod = 998244353;
int qmi(int a, int b, int mod){
int res = 1 % mod;
while(b){
if (b & 1) res = res * a % mod;
a = a * a % mod;
b >>= 1;
}
return res;
}
int C(int a, int b){
int ans = 1, res = 1;
for (int i = a, j = 1; j <= b; i --, j ++){
ans = ans * i % mod;
res = res * j % mod;
}
return (ans * qmi(res, mod - 2, mod) % mod) % mod;
}
signed main(){
int T;
scanf("%lld", &T);
int t = 1;
while(T --){
int n;
scanf("%lld", &n);
int ans = (C(2 * n, n) * qmi(n + 1, mod - 2, mod) % mod - C(2 * n - 2, n - 1) * qmi(n, mod - 2, mod) % mod % mod + mod) % mod;
printf("Case #%lld: %lld\n", t ++, ans);
}
}