题意:
给出一个字符串只包含左右括号,问长度为n,n为偶数,前n/2是(,后n/2是)的子串的个数
思路:
对于每一个左括号所在的位置,假设它左边包括自己有m个左括号,右边有n个右括号,那么这个左括号所能做出的子串的贡献数就是
然后用下范德蒙恒等式:就能做出来了。
代码:
#include <bits/stdc++.h>
using namespace std;
#define LL long long
const int mod=1e9+7;
const int maxn=200100;
char str[200123];
LL num[200123];
LL fac[200123];
LL nfac[200123];
LL qmod(LL m, LL n)
{
LL res=1;
while(n)
{
if(n&1)res=(res*m)%mod;
m=m*m%mod;
n>>=1;
}
return res;
}
void init()
{
int i, j;
fac[1]=1LL;
for(i=2; i<=maxn; i++)
{
fac[i]=(1LL*i*fac[i-1])%mod;
}
nfac[maxn]=qmod(fac[maxn],mod-2)%mod;
for(i=maxn-1; i>=0; i--)
{
nfac[i]=(nfac[i+1]*(LL)(i+1))%mod;
}
}
/*LL cal(LL m, LL n)
{
if(n==0)return 1LL;
LL i;
LL res=1;
for(i=1; i<=n; i++)
{
res=(res*(m-i+1LL)/i)%mod;
}
// cout<<res<<endl;
return res%mod;
}
*/
LL cal(LL m, LL n)
{
return fac[m+n-1]*nfac[m]%mod*nfac[n-1]%mod;
}
int main()
{
init();
scanf("%s", str);
int i;
LL a=0, b=0;
for(i=0; str[i]; i++)
{
if(str[i]=='(')a++;
else b++;
}
LL ans=0;
LL j=0;
for(i=0; str[i]; i++)
{
if(str[i]=='(')
{
j++;
// cout<<j<<" "<<b<<endl;
ans=(ans+cal(j, b))%mod;
}
else b--;
}
cout<<ans%mod<<endl;
}