首页 > 其他分享 >NC20277 [SCOI2010]字符串

NC20277 [SCOI2010]字符串

时间:2023-08-26 23:22:05浏览次数:47  
标签:return int namespace invfact leq 字符串 NC20277 SCOI2010

题目链接

题目

题目描述

lxhgww最近接到了一个生成字符串的任务,任务需要他把n个1和m个0组成字符串,但是任务还要求在组成的字符串中,在任意的前k个字符中,1的个数不能少于0的个数。现在lxhgww想要知道满足要求的字符串共有多少个,聪明的程序员们,你们能帮助他吗?

输入描述

输入数据是一行,包括2个数字n和m

输出描述

输出数据是一行,包括1个数字,表示满足要求的字符串数目,这个数可能会很大,只需输出这个数除以20100403的余数

示例1

输入

2 2

输出

2

备注

对于30%的数据,保证 \(1\leq m\leq n\leq 10^3\) 。
对于100%的数据,保证 \(1\leq m\leq n\leq 10^6\) 。

题解

知识点:卡特兰数。

这道题是卡特兰数的变种,即终点不在 \((n,n)\) 而在 \((n,m)(n \geq m)\) 。

思路是完全一样的,任意非法路径沿 \(y = x+1\) 翻折,将唯一对应一条终点在 \((m-1,n+1)\) 的路径,同时任意一条终点在 \((m-1,n+1)\) 的路径都对应一条非法路径,所以这两者是一一对应的。因此,答案是 \(\dbinom{n+m}{m} - \dbinom{n+m}{m-1}\) 。

时间复杂度 \(O(n+m)\)

空间复杂度 \(O(n+m)\)

代码

#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;
}

标签:return,int,namespace,invfact,leq,字符串,NC20277,SCOI2010
From: https://www.cnblogs.com/BlankYang/p/17659678.html

相关文章

  • Java字符串替换
    JavaStringreplaceAll详解总结:Java编译期\为转义符,运行期正则表达式\为转义符,正则表达式匹配\需使用\\。replace为普通字符串替换,replaceAll为正则表达式替换(第一个参数为正则表达式,第二个参数中\为转义字符,$为正则字符),第二个参数表示\需使用\\。示例:替换字符串中的""......
  • .bat批处理(十):从路径字符串中截取盘符、文件名、后缀名等信息
    文章目录前言`%~dp0`的含义扩展字符串从字符串中截取路径、文件名脚本传参for语法扩展总结 前言又是实际开发中的问题,想要截取一个文件路径中的盘符、文件名等信息,第一反应是正则表达式?或者是split函数?这些往往都是“高级”语言中才会有的实现方法,对于批处......
  • 两种不同的方法来检查Python中的变量是否是字符串
    在Python中,每个变量都有一个数据类型。数据类型表示一个变量内部存储的是哪种数据。数据类型是编程语言最重要的特征,它区分了我们可以存储的不同类型的数据,如字符串、int和float。在处理许多编程问题时,可能会遇到这样的情况:我们需要找到某个变量的数据类型来对其执行一些任务。......
  • JSON字符串的几种格式
    1.JSON数值{“key”:value}{"key":520,"key1":1314}2.JSON字符串{“key”:“value”}{"key":"我爱你","key1":"一生一世"}3.JSON数组{“key”:[value]}{"key":[520,1314]......
  • 大厂算法每日总结(GB字符串至少交换几次)
    //一个数组中只有两种字符'G'和'B',//想要所有的G都放左边,所有的B都放右边或者所有的B都放左边,所有的G都放右边//但只能在相邻字符之间进行交换操作//返回至少需要交换几次//方法1publicstaticintminSteps1(Strings){if(s==null||s.equals("")){return0;}......
  • 将中文字符串转换为拼音
    Python中可以使用第三方库pypinyin来将中文字符串转换为拼音。下面是一个示例代码:frompypinyinimportlazy_pinyinchinese_str="钱文敏"pinyin_str=''.join(lazy_pinyin(chinese_str))abbreviated_pinyin_str=chinese_str[0]+pinyin_strprint(abbreviated_pinyin_s......
  • 函数-字符串函数
      ......
  • mysql字符串替换 replace方法替换字段中的值
    需求:字符串A是一个JSON字符串,其中的属性值可能为空吗,例如字段”result“{"处理结果":{"字段A":{"结果":""},......,{"字段X":{"结果”:""}}}需求:如果其中的结果为空则将 {"结果":""}替换为""selectreplace(result,'{"......
  • c语言 字符指针,字符串的输出
    @TOC前言一、字符指针初始化:一般写法:char*str="hellowyy";完美写法:constchar*str="hellowyy";注释:const就是常的意思,常量指针,指向常量字符串,因为字符串就是自身的数组名字。相当于:chara[10];char*str=a;字符串中间有\0:字符串只找结尾。若中间有\0,则字符串......
  • 字符串处理C++
    1、字符串连接题目描述不借用任何字符串库函数实现无冗余地接受两个字符串,然后把它们无冗余的连接起来。输入每一行包括两个字符串,长度不超过100。输出可能有多组测试数据,对于每组数据,不借用任何字符串库函数实现无冗余地接受两个字符串,然后把它们无冗余的连接起来。输出连接......