题目链接:https://www.nowcoder.com/acm/contest/146/B
把前四项丢进OEIS,就能知道是
施罗德数
参照百科:https://baike.baidu.com/item/%E6%96%BD%E7%BD%97%E5%BE%B7%E6%95%B0/16536292
施罗德数是一组可用于解决组合数学中某些问题的序列。
施罗德数的前几项为1, 2, 6, 22, 90, 394, 1806, 8558, 41586, 206098,... (OEIS A006318)
但是按照施罗德数
递推公式暴力肯定会超时,在网上搜索“施罗德数”可以查到“超级卡特兰数”,其递推公式为:
数列前几项为1, 1, 3, 11, 45, 197, 903, 4279, 20793, 103049, 518859, 2646723, 13648869, 71039373, 372693519, 1968801519, 10463578353, 55909013009, 300159426963, 1618362158587, 8759309660445, 47574827600981, 259215937709463……(从第0项开始的)
仔细观察可以看到这个数列和施罗德数除了f(1)以外都是2倍的关系,所以可以使用这个公式计算。
代码如下:
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=3e5;
typedef long long LL;
#define mod 998244353
LL num[maxn];
LL inverse(LL x,LL y)///快速幂加费马小定理求逆元
{
LL sum=1;
while(y)
{
if(y&1) sum=sum*x%mod;
y/=2;
x=x*x%mod;
}
return sum%mod;
}
int main()
{
int n;
while(~scanf("%d",&n))
{
num[1]=num[0]=1;
if(n==1) {
printf("1\n");continue;
}
for(int i=2;i<=n;i++)
{
num[i]=((6*i-3)*num[i-1]%mod-(i-2)*num[i-2]%mod+mod)%mod*inverse(i+1,mod-2)%mod;
}
printf("%lld\n",num[n-1]*2%mod);
}
return 0;
}
我的标签:做个有情怀的程序员。