zoukankan      html  css  js  c++  java
  • Bzoj 1856: [Scoi2010]字符串 卡特兰数,乘法逆元,组合数,数论

    1856: [Scoi2010]字符串

    Time Limit: 5 Sec  Memory Limit: 64 MB
    Submit: 1194  Solved: 651
    [Submit][Status][Discuss]

    Description

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

    Input

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

    Output

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

    Sample Input

    2 2

    Sample Output

    2

    HINT

    【数据范围】
    对于30%的数据,保证1<=m<=n<=1000
    对于100%的数据,保证1<=m<=n<=1000000

    Source

    Day2

    题解:

    在任意的前k个字符中,1的个数不能少于0的个数 ???

    好熟悉。。。卡特兰数。。。

    当然你也可以在纸上推一下。

    直接套公式:当n为1的个数,m为0的个数时,卡特兰数为C(n+m,n)-C(n+m,m-1)。

    组合数C(n,r)直接用逆元计算即可。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define MOD 20100403
     4 #define LL long long
     5 LL ksm(LL bb,LL pp,LL kk)
     6 {
     7     LL s=1;
     8     while(pp>0)
     9     {
    10         if(pp%2!=0)s=(s*bb)%kk;
    11         pp/=2;
    12         bb=(bb*bb)%kk;
    13     }
    14     return s;
    15 }
    16 LL C(LL n,LL m)
    17 {
    18     LL s1=1,s2=1,nn=n,i;
    19     if(m>n-m)m=n-m;
    20     for(i=1;i<=m;i++)
    21     {
    22         s1=(s1*nn)%MOD;nn--;
    23         s2=(s2*i)%MOD;
    24     }
    25     return (s1*ksm(s2,MOD-2,MOD))%MOD;
    26 }
    27 int main()
    28 {
    29     LL n,m;
    30     scanf("%lld %lld",&n,&m);
    31     printf("%lld",((C(n+m,n)-C(n+m,m-1))%MOD+MOD)%MOD);
    32     fclose(stdin);
    33     fclose(stdout);
    34     return 0;
    35 }
  • 相关阅读:
    【Java】REST风格
    KMP(烤馍片)算法
    Lca求法 (树链剖分 与 倍增)
    hash学习笔记
    星际网络(数学)
    P3537 [POI2012]SZA-Cloakroom (背包)
    乘车路线 (二维最短路)
    渔民的烦恼 (二分)
    Jmeter 常用函数(18)- 详解 __isDefined
    Jmeter 常用函数(17)- 详解 __substring
  • 原文地址:https://www.cnblogs.com/Var123/p/5318006.html
Copyright © 2011-2022 走看看