zoukankan      html  css  js  c++  java
  • HDU 6084 寻找母串(卡特兰数)

    【题目链接】 http://acm.hdu.edu.cn/showproblem.php?pid=6084

    【题目大意】

      对于一个串S,当它同时满足如下条件时,它就是一个01偏串:
        1.只由0和1两种符组成;
        2.在S的每一个前缀中,0的个数不超过1的个数;
        3.S中0的个数和1的个数相等。
      现在给定01偏串S,请计算一下S在所有长度为n的01偏串中作为子串出现的次数的总和。
      由于结果比较大,结果对1e9+7取余后输出。

    【题解】

      我们发现01偏串实际上等价于合法括号序列,
      在合法括号序列中取出一个合法括号序列之后剩下的一定也是一个合法括号序列
      所以我们计算n-lenS的合法括号序列数,乘上S在n中的位置种类即可,
      计算卡特兰数时候因为模比较大,我们采用分段打表。
      注意n-s<0||(n-s)%2==1条件的特判。

    【代码】

    #include <cstdio>
    #include <algorithm>
    #include <cstring> 
    using namespace std;
    typedef long long LL;
    const LL MOD=1000000007,blk=500000;
    const LL lst[2001]={……};
    int T,n,s;
    char ss[1000010];
    LL Fact(LL x){
        if(x<0)return 0;
        LL res=lst[x/blk];
        for(LL i=(x/blk)*blk+1;i<=x;i++)res=(res*i)%MOD;
        return res;
    }
    LL power(LL a,LL b){
        if(b==0)return 1;
        if(b&1)return(power(a,b-1)*a)%MOD;
        LL t=power(a,b/2);return (t*t)%MOD;
    }
    LL C(LL a,LL b){
        if(a<0||b<0||a<b)return 0;
        return(Fact(a)*power(Fact(a-b),MOD-2)%MOD*power(Fact(b),MOD-2))%MOD;
    }
    LL Calc(int x){return (C(2*x,x)-C(2*x,x-1)+MOD)%MOD;}
    int main(){
        scanf("%d",&T);
        while(T--){
            scanf("%d %s",&n,ss);
            s=strlen(ss);
            if(n-s<0||(n-s)%2==1)puts("0"); 
            else printf("%d
    ",Calc((n-s)/2)*(n-s+1)%MOD);
        }return 0;
    }
  • 相关阅读:
    vue+springboot+element+vue-resource实现文件上传
    使用bfg快速清理git历史大文件
    git clone异常 【fatal: protocol error: bad line length character: Inte】
    excel 一次删除所有空行
    vim编辑器
    prometheus安装
    递归计算分波那契数列和阶乘
    如何理解线程安全?
    创建线程的方式
    为什么说一个对象是线程安全的?
  • 原文地址:https://www.cnblogs.com/forever97/p/hdu6084.html
Copyright © 2011-2022 走看看