zoukankan      html  css  js  c++  java
  • BZOJ1856:[SCOI2010]字符串(卡特兰数,组合数学)

    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

    Solution

    只要看懂这个博客方法二的证明,就可以发现这个题只不过是那个证明变了一点而已。

    只需要做起点的对称点用总路径减去不合法路径即可。
    最后答案是C(m+n,n)-C(m+n,n+1)

    Code

     1 #include<iostream>
     2 #include<cstdio>
     3 #define N (2000000+1000)
     4 #define MOD (20100403)
     5 using namespace std;
     6 long long n,m,Fact[N],FactInv[N],Inv[N],ans;
     7 
     8 long long C(long long n,long long m)
     9 {
    10     if (m>n) return 0;
    11     return Fact[n]*FactInv[m]%MOD*FactInv[n-m]%MOD;
    12 }
    13 
    14 int main()
    15 {
    16     scanf("%lld%lld",&n,&m);
    17     Inv[0]=Inv[1]=Fact[0]=Fact[1]=1;
    18     for (int i=2; i<=m+n; ++i)
    19     {
    20         Fact[i]=Fact[i-1]*i%MOD;
    21         Inv[i]=(MOD-MOD/i)*Inv[MOD%i]%MOD;
    22     }
    23     
    24     FactInv[0]=1;
    25     for (int i=1; i<=m+n; ++i)
    26         FactInv[i]=Inv[i]*FactInv[i-1]%MOD;
    27     printf("%lld",((C(m+n,n)-C(m+n,n+1))%MOD+MOD)%MOD);
    28 }
  • 相关阅读:
    HDOJ 1202 The calculation of GPA
    HDOJ 1197 Specialized Four-Digit Numbers
    HDOJ 1196 Lowest Bit(二进制相关的简单题)
    HDOJ 1194 Beat the Spread!(简单题)
    NOIP2018游记
    CF1043
    洛谷P1280 尼克的任务
    洛谷P1155 双栈排序
    SPOJ6340 ZUMA
    chessboard
  • 原文地址:https://www.cnblogs.com/refun/p/9281271.html
Copyright © 2011-2022 走看看