NC20277 [SCOI2010]字符串
题目
题目描述
lxhgww最近接到了一个生成字符串的任务,任务需要他把n个1和m个0组成字符串,但是任务还要求在组成的字符串中,在任意的前k个字符中,1的个数不能少于0的个数。现在lxhgww想要知道满足要求的字符串共有多少个,聪明的程序员们,你们能帮助他吗?
输入描述
输入数据是一行,包括2个数字n和m
输出描述
输出数据是一行,包括1个数字,表示满足要求的字符串数目,这个数可能会很大,只需输出这个数除以20100403的余数
示例1
输入
2 2
输出
2
备注
对于30%的数据,保证 。
对于100%的数据,保证 。
题解
知识点:卡特兰数。
这道题是卡特兰数的变种,即终点不在 而在 。
思路是完全一样的,任意非法路径沿 翻折,将唯一对应一条终点在 的路径,同时任意一条终点在 的路径都对应一条非法路径,所以这两者是一一对应的。因此,答案是 。
时间复杂度
空间复杂度
代码
#include <bits/stdc++.h> using namespace std; using ll = long long; const int P = 20100403; namespace Number_Theory { const int N = 2e6 + 7; int qpow(int a, ll k) { int ans = 1; while (k) { if (k & 1) ans = 1LL * ans * a % P; k >>= 1; a = 1LL * a * a % P; } return ans; } int fact[N], invfact[N]; void init(int n) { fact[0] = 1; for (int i = 1;i <= n;i++) fact[i] = 1LL * i * fact[i - 1] % P; invfact[n] = qpow(fact[n], P - 2); for (int i = n;i >= 1;i--) invfact[i - 1] = 1LL * invfact[i] * i % P; } } namespace CNM { using namespace Number_Theory; int C(int n, int m) { if (n == m && m == -1) return 1; //* 隔板法特判 if (n < m || m < 0) return 0; return 1LL * fact[n] * invfact[n - m] % P * invfact[m] % P; } } namespace Catalan { int F(int n, int m) { return (CNM::C(n + m, m) - CNM::C(n + m, m - 1) + P) % P; } int H(int n) { return F(n, n); } } /// Catalan数,O(n),质数模数下利用组合数快速求出Catalan数 //* F为推广形式,在合法条件下到达任意终点(n,m)的方案数(n >= m) int main() { std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0); int n, m; cin >> n >> m; Number_Theory::init(n + m); cout << Catalan::F(n, m) << '\n'; return 0; }
本文来自博客园,作者:空白菌,转载请注明原文链接:https://www.cnblogs.com/BlankYang/p/17659678.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧