Codeforces Round #404 D. Anton and School - 2 (范德蒙恒等式+组合数)
2017-03-16 10:45
309 查看
D. Anton and School - 2
题意
给定一个字符串 s ,只含有字符(和
)。问 s 有多少个子序列 sub ,满足如下条件:
sub 不为空串
sub 为偶数长度
sub 串的前半串均为
(
sub 串的后半串均为
)
分析
应该比较容易能得到一个公式:对于串 s ,对串的每一个字符进行枚举。
如果第 i 个字符为
),不考虑该字符对答案的贡献(
(与
)对称,若统计对答案相当于
乘2效果,重复计算)
如果第 i 个字符为
(,则该字符对答案的贡献为:
令该
(的左边有 preX[i-1] 个
(,该
(的右边有 sufY[i+1] 个
)。
ans+=Σmin(preX[i], sufY[i+1])j=0CjpreX[i]×CjsufY[i+1]−Σmin(preX[i−1], sufY[i+1])j=0CjpreX[i−1]×CjsufY[i+1]
很显然直接套用该公式会 T。
但是,该公式可以套用 范德蒙恒等式 的一个推论化简。
范德蒙恒等式: 推论:Ckm+nCmm+n=Σki=0Cim×Ck−in=Σmi=0Cim×Cinm≤n
故公式可化简为:
ans+=Cmin(preX[i],sufY[i+1])preX[i]+sufY[i+1]−Cmin(preX[i−1],sufY[i+1])preX[i−1]+sufY[i+1]
至于计算组合数 ,可通过乘法逆元快速求取(数值范围过大,打表预处理行不通)。
代码
#include<bits/stdc++.h> using namespace std; const int LEN = 200000 + 10; const int mod = 1e9 + 7; char s[LEN]; int preX[LEN], sufY[LEN]; long long pre[LEN]; //----------------求组合数 ----------// // ------ 乘法逆元 --------// int extend_gcd(int a, int b, int &x, int &y) { if(b==0) { x = 1; y = 0; return a; } else { int r = extend_gcd(b, a%b, y, x); y -= x*(a/b); return r; } } int mod_inverse(int b, int p) { int x, y; extend_gcd(b, p, x, y); return (x % p + p) % p; } //-------乘法逆元 END-------// long long C(int n, int i) { if(i == n || i == 0) return 1; long long fac = pre * mod_inverse(pre[n-i], mod); fac %= mod; return (fac * mod_inverse(pre[i], mod)) % mod; } //----------------求组合数 END ----------// void init() { pre[1] = 1; for(int i=2;i<LEN;i++) { pre[i] = pre[i-1] * i; if(pre[i] > mod) pre[i] %= mod; } } int main() { init(); scanf(" %s",s); int len = strlen(s); preX[0] = s[0] == '(' ? 1 : 0; for(int i=1;i<len;i++) preX[i] = preX[i-1] + (s[i] == '(' ? 1 : 0); for(int i=len-1;i>=0;i--) sufY[i] = sufY[i+1] + (s[i] == ')' ? 1 : 0); long long ans = 0; for(int i=0;i<len;i++) { if(i && preX[i] == preX[i-1]) continue; ans += C(preX[i] + sufY[i+1], min(preX[i], sufY[i+1])); ans -= C(preX[i-1] + sufY[i+1], min(preX[i-1], sufY[i+1])); (ans %= mod) += mod; } printf("%d\n",ans % mod); }
相关文章推荐
- Codeforces Round #379 (Div. 2) F. Anton and School
- 【组合数】【乘法逆元】 Codeforces Round #404 (Div. 2) D. Anton and School - 2
- Codeforces Round #379 (Div. 2) F. Anton and School
- Codeforces Round #404 (Div. 2) D. Anton and School - 2 前缀的后缀、 范德蒙恒等式、容斥
- Anton and School - 2 (组合数学)
- CodeForces 785D Anton and School - 2 组合数学
- Codeforces Round #379 (Div. 2) F. Anton and School
- codeforces 785 D Anton and School - 2(组合数学)
- codeforces 785 D. Anton and School - 2
- Codeforces785 D. Anton and School - 2 组合数学
- [CF785D]Anton and School - 2
- Codeforces 785D - Anton and School - 2(范德蒙恒等式+逆元)
- Codeforces Round #404 (Div. 2) D. Anton and School - 2 [范德蒙恒等式]
- #404 (div2)Anton and School - 2
- 【codeforces 785D】Anton and School - 2
- [codeforces 734F]Anton and School
- Codeforces 785 D. Anton and School - 2
- Codeforces Round #404 D. Anton and School - 2 (范德蒙恒等式+逆元求组合数)
- 【数论】Codeforces Round #404 (Div. 2)(D)Anton and School - 2
- 数学(Anton and School,cf 734F)