题意:给你一个由‘(‘和‘)‘组成的字符串,问你有多少个子串,前半部分是由‘(‘组成后半部分由‘)‘组成
思路:枚举这个字符串中的所有‘(‘左括号,它左边的所有‘(‘左括号的个数为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; }
时间: 2024-10-14 16:59:17