• CF785D Anton and School


    Solution

    这个题经过一番思考,发现前面一位和后面一位之间是不会相互影响的,也就是各自的贡献是独立算的。

    那我们就直接通过一些排列组合的方式来求出答案即可。

    刚刚我提到了贡献,所以我们可以对这个括号序列的每一位进行计算,最后相加。然后发现因为他们是成对匹配的,当你算左括号的时候,右括号已经被算了一遍,算右括号的时候,左括号被算了一次,会重复计算。那么就只考虑左括号就行了。

    记录当前位左边有多少左括号(包括自己),右边有多少右括号,设有 (a) 个左括号, (b) 个右括号,那么满足条件的子串会多 (C_{a-1}^0C_b^1+C_{a-1}^1C_b^2+cdots+C_{a-1}^xC_{b}^{x+1}+cdots=sumlimits_{i=0}^{min(a-1,b-1)}C_{a-1}^xC_b^{x+1})

    然后有个神奇的东西叫范德蒙德卷积,它是长这个样子的: (sumlimits_{i=0}^kC_n^iC_m^{k-i}=C_{n+m}^k)

    原题中的式子我们也可以类似的转化: (sumlimits_{i=0}^{min(a-1,b-1)}C_{a-1}^xC_b^{x+1}=sumlimits_{i=0}^{min(a-1,b-1)}C_{a-1}^{a-x-1}C_b^{x+1}=C_{a+b-1}^a)

    呜呼,那么我们只要预处理出每一位的左括号,右括号和组合数就好了。

    时间复杂度: (O(len_s))

    代码

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<iostream>
    #include<algorithm>
    #define ll long long
    
    using namespace std;
    const int N=200010,mod=1e9+7;
    char s[N];
    int l[N],r[N];
    ll ans,fac[N],inv[N];
    
    ll fpow(ll a,ll b){
        ll res=1;
        while(b){
            if(b&1) res=res*a%mod;
            a=a*a%mod;
            b>>=1;
        }
        return res;
    }
    
    inline void init(){
        fac[0]=1;
        for(int i=1;i<=200000;i++) fac[i]=fac[i-1]*i%mod;
        inv[200000]=fpow(fac[200000],mod-2);
        for(int i=200000;i>=1;i--) inv[i-1]=inv[i]*i%mod;
    }
    
    inline ll C(ll n,ll m){
        if(n<m) return 0;
        return fac[n]*inv[n-m]%mod*inv[m]%mod;
    }
    
    int main(){
        init();
        scanf("%s",s+1);
        int len=strlen(s+1);
        for(int i=1;i<=len;i++)
            l[i]=(s[i]=='('?l[i-1]+1:l[i-1]);
        for(int i=len;i>=1;i--)
            r[i]=(s[i]==')'?r[i+1]+1:r[i+1]);
        for(int i=1;i<=len;i++)
            if(s[i]=='(') ans=(ans+C(l[i]+r[i]-1,l[i]))%mod;
        printf("%lld
    ",ans);
        return 0;
    }
    
  • 相关阅读:
    泛型约束 where T : class,new()
    在Navicat for MySQL中打开视图时,提示视图没有主键的问题
    转:JQuery实现下拉框的数据加载和联动
    查询每门课程最高分的学生的学号,课程号,成绩
    转:SQL子句的执行顺序
    端口映射
    服务器与个人电脑的区别
    花生壳使用指南
    如何测试本机的公网IP能否被Internet用户访问
    利用ADSL拨号上网方式如何搭建服务器
  • 原文地址:https://www.cnblogs.com/jasony/p/13817518.html
Copyright © 2020-2023  润新知