• CodeForces 785D Anton and School


    题意:

    给你一串括号 问你有多少种匹配的子串

    就是前半部分都是'(' 后半部分都是')'的子串

    思路:

    首先我们预处理

    当前位置之前有多少左括号 和 当前位置之后有多少右括号

    对于每一个处于i位置的左括号

    我们将ans+=C(left[i]+right[i]-1,right[i]-1)

    这个式子是C(i-1,left[i]-1)*C(i+1,right[i])化简来的

    因为选的数总数是不变的 所以可以化简(?)

    就是从左边选i-1个左括号 从右边选i+1个右括号

    因为自己是必选的 所以左括号-1

     1 #include<bits/stdc++.h>
     2 #define cl(a,b) memset(a,b,sizeof(a))
     3 #define debug(a) cerr<<#a<<"=="<<a<<endl
     4 using namespace std;
     5 typedef long long ll;
     6 typedef pair<int,int> pii;
     7 
     8 const int maxn=2e5+10;
     9 const int mod=1e9+7;
    10 
    11 ll fac[maxn];
    12 
    13 ll quick_pow(ll a,ll n)
    14 {
    15     ll ans=1;
    16     while(n)
    17     {
    18         if(n%2) ans=1ll*ans*a%mod;
    19         a=1ll*a*a%mod;
    20         n>>=1;
    21     }
    22     return ans;
    23 }
    24 
    25 ll inv(ll a)
    26 {
    27     return quick_pow(a,mod-2);
    28 }
    29 
    30 void init()
    31 {
    32     fac[0]=1;
    33     for(int i=1;i<maxn;i++)
    34     {
    35         fac[i]=1ll*fac[i-1]*i%mod;
    36     }
    37 }
    38 
    39 ll C(ll a,ll b)
    40 {
    41     ll ans=1;
    42     if(a<b || b<0) return 0;
    43     while(a&&b)
    44     {
    45         ll aa=a%mod,bb=b%mod;
    46         if(aa<bb) return 0;;
    47         ans = 1ll*ans*fac[aa]%mod * inv(1ll*fac[bb]*fac[aa-bb]%mod)%mod;
    48         a/=mod,b/=mod;
    49     }
    50     return ans;
    51 }
    52 
    53 int main()
    54 {
    55     string str;
    56     cin>>str;
    57     int sz=str.size();
    58     vector<int>left(sz,0),right(sz,0);
    59     if(str[0]=='(') left[0]=1;
    60     for(int i=1;i<sz;i++)
    61     {
    62         left[i]=left[i-1]+(str[i]=='(');
    63     }
    64     if(str[sz-1]==')') right[sz-1]=1;
    65     for(int i=sz-2;i>=0;i--)
    66     {
    67         right[i]=right[i+1]+(str[i]==')');
    68     }
    69     ll ans=0;
    70     init();
    71     for(int i=0;i<sz;i++)
    72     {
    73         if(str[i]=='(')
    74         {
    75             ans+=C(left[i]+right[i]-1,right[i]-1);
    76             ans%=mod;
    77         }
    78     }
    79     cout<<ans<<endl;
    80     return 0;
    81 }/*
    82 
    83 )(()()
    84 
    85 */
  • 相关阅读:
    MySQL官方文档-二级索引覆盖主键索引
    windows server 2008/win7 远程控制
    博客园美化日记
    MarkDown 中使用 LaTeX 数学式
    DOS命令和bat脚本
    数据链路层
    网络安全
    运输层安全协议SSL
    DNS/域名
    停止等待协议
  • 原文地址:https://www.cnblogs.com/general10/p/7224626.html
Copyright © 2020-2023  润新知