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

[Codeforces 785 D.Anton and School - 2](http://codeforces.com/problemset/problem/785/D) 题目大意:从一串由“(”,“)”组成的字符串中,找出有多少个子序列满足:序列长度为偶数,且前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)。 组合数预处理: ```C++ 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=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]); } ``` 解题代码: ```C++ #include #include #include #include #include #include #include #include #include #include #include using namespace std; typedef long long ll; typedef pair P; typedef map M; typedef queue Q; typedef set S; typedef vector 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=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;
}

</font>
posted @ 2018-06-07 16:26  __orange  阅读(127)  评论(0编辑  收藏  举报