首页 > 代码库 > CF #404 (Div. 2) D. Anton and School - 2 (数论+范德蒙恒等式)

CF #404 (Div. 2) D. Anton and School - 2 (数论+范德蒙恒等式)

题意:给你一个由‘(‘和‘)‘组成的字符串,问你有多少个子串,前半部分是由‘(‘组成后半部分由‘)‘组成

思路:枚举这个字符串中的所有‘(‘左括号,它左边的所有‘(‘左括号的个数为num1,它的右边的所有’)‘右括号的个数为num2,

技术分享

根据范德蒙恒等式计算得出

 

代码:

#include <bits/stdc++.h>
#define ll long long
#define maxn 200000
#define mod 1000000007
using namespace std;

ll jc[maxn+5];

void get_jc()
{
    jc[0]=1;
    for(int i=1;i<=maxn;i++)
    {
        jc[i]=(jc[i-1]*i)%mod;
    }
}

ll qmod(ll a,ll b)
{
    ll ans=1;
    while(b)
    {
        if(b%2==1)
        {
            ans=(ans*a)%mod;
        }
        b=b/2;
        a=(a*a)%mod;
    }
    return ans;
}

ll get_C(ll m,ll n)
{
    return (jc[m]*qmod((jc[m-n]*jc[n])%mod,mod-2))%mod;
}

int main()
{
    string data;
    int num1[maxn+5],num2[maxn+5];
    get_jc();
    while(cin>>data)
    {
        int p=0;
        for(int i=0;i<data.length();i++)
        {
            if(data[i]==()
            {
                p++;
            }
            num1[i]=p;
        }
        p=0;
        ll ans=0;
        for(int i=data.length()-1;i>=0;i--)
        {
            if(data[i]==))
            {
                p++;
            }
            num2[i]=p;
        }
        for(int i=0;i<data.length();i++)
        {
            if(data[i]==()
            {
                ans=(ans+get_C(num1[i]+num2[i]-1,num2[i]-1))%mod;
            }
        }
        cout<<ans<<endl;
    }
    return 0;
}

 

CF #404 (Div. 2) D. Anton and School - 2 (数论+范德蒙恒等式)