Codeforces 785 D.Anton and School - 2(组合数处理)


Codeforces 785 D.Anton and School - 2
题目大意:从一串由“(”,“)”组成的字符串中,找出有多少个子序列满足:序列长度为偶数,且前n/2个为“(”,后n/2个为“)”;
思路:枚举每一个左括号,则以该左括号为左右分界的子序列个数为∑C(L-1,i)C(R,i+1)(其中L为该左括号向左的左括号数,R为该左括号向右的右括号数,i从0累加到L-1)。而∑C(L-1,i)C(R,i+1)=∑C(L-1,L-1-i)C(R,i+1)=C(L+R-1,L)。
组合数预处理:

const int maxn=2e5+10,mod=1e9+7;
ll jc[maxn],inv[maxn];
ll kpow(ll a,ll x)
{
    ll res=1;
    while (x)
    {
        if (x&1)
            res=res*a%mod;
        a=a*a%mod;
        x>>=1;
    }
    return res;
}
void init()
{
    jc[0]=1;
    for (int i=1;i<maxn;++i)
    {
        jc[i]=jc[i-1]*i%mod;
    }
    inv[maxn-1]=kpow(jc[maxn-1],mod-2);
    for (int i=maxn-2;i>=0;--i)
    {
        inv[i]=inv[i+1]*(i+1)%mod;;
    }
}
inline ll C(ll n,ll m)
{
    if (m>n)
        return 0;
    return mul(mul(jc[n],inv[m]),inv[n-m]);
}

解题代码:

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<map>
#include<stack>
#include<queue>
#include<set>
#include<cmath>
#include<algorithm>
#include<climits> 
using namespace std;
typedef long long ll;
typedef pair<int,int> P;
typedef map<int,int> M;
typedef queue<int> Q;
typedef set<int> S;
typedef vector<int> V;
const int maxn=2e5+10,mod=1e9+7;
inline ll add(ll a,ll b)
{
    a+=b;
    if (a>=mod)
        a-=mod;
    if (a<0)
        a+=mod;
    return a;
}
inline ll mul(ll a,ll b)
{
    return a*b%mod;
}
ll jc[maxn],inv[maxn];
ll kpow(ll a,ll x)
{
    ll res=1;
    while (x)
    {
        if (x&1)
            res=res*a%mod;
        a=a*a%mod;
        x>>=1;
    }
    return res;
}
void init()
{
    jc[0]=1;
    for (int i=1;i<maxn;++i)
    {
        jc[i]=jc[i-1]*i%mod;
    }
    inv[maxn-1]=kpow(jc[maxn-1],mod-2);
    for (int i=maxn-2;i>=0;--i)
    {
        inv[i]=inv[i+1]*(i+1)%mod;;
    }
}
inline ll C(ll n,ll m)
{
    if (m>n)
        return 0;
    return mul(mul(jc[n],inv[m]),inv[n-m]);
}

char s[maxn];
int main()
{
    std::ios::sync_with_stdio(0);
    cin.tie(0);
    int i,j,m,n,k,l=0,r=0;  
    cin>>s;
    n=strlen(s);
    init();
    for (i=0;i<n;++i)
    {
        r+=s[i]==')';
    }
    ll ans=0;
    for (i=0;i<n;++i)
    {
        l+=s[i]=='(';
        r-=s[i]==')';
        if (s[i]=='(')
            ans=add(ans,C(l+r-1,l));}
    cout<<ans;
    return 0;
}
 

猜你喜欢

转载自www.cnblogs.com/orangee/p/9151343.html