卡特兰数、

链接: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);
	}
}

猜你喜欢

转载自blog.csdn.net/qq_45772483/article/details/112596735