codeforces 785d[补]
2017-03-18 21:13
387 查看
题目:http://codeforces.com/problemset/problem/785/D
题目意思:
有一个只有’(‘和’)’的串,可以随意的删除随意多个位置的符号,现在问能构成((((((…((()))))….))))))这种对称的情况有多少种,保证中间对称,左边为’(‘右边为’)’
一道比赛的时候看了一眼,读错题感觉只能做出O(n^2)的前后缀数组的方法,想了几分钟没想出思路去继续搞c。。结果c依然爆炸,后来回去之后又看了看题,太晚了没敢继续敲。。
当时想着思路大概是前后缀数组,然后组合数学。
起床之后推出了这个
然后有点懵。。这个时间复杂度是O(n^2)的啊,然后。。就没有然后了,默默的看了下题解。。他们公式都是长这样的
当然,如果 n>m ,对应位置组合数为0,结论不变。 所以C上面那个数为last[i] - 1
为什么呢。。因为我自己组合数学没学好。要通过范德蒙恒等式来进行转换。。弱弱的给个链接http://blog.csdn.net/acdreamers/article/details/31032763
然后,对于阶层,很容易乘爆,而且组合数学是需要除的,所以需要用到乘法逆元,再给个链接。http://blog.csdn.net/daniel_csdn/article/details/50783734
这一道题数学知识涨得很多,很欣慰。
记一发阶层逆元的代码
题目意思:
有一个只有’(‘和’)’的串,可以随意的删除随意多个位置的符号,现在问能构成((((((…((()))))….))))))这种对称的情况有多少种,保证中间对称,左边为’(‘右边为’)’
一道比赛的时候看了一眼,读错题感觉只能做出O(n^2)的前后缀数组的方法,想了几分钟没想出思路去继续搞c。。结果c依然爆炸,后来回去之后又看了看题,太晚了没敢继续敲。。
当时想着思路大概是前后缀数组,然后组合数学。
起床之后推出了这个
然后有点懵。。这个时间复杂度是O(n^2)的啊,然后。。就没有然后了,默默的看了下题解。。他们公式都是长这样的
当然,如果 n>m ,对应位置组合数为0,结论不变。 所以C上面那个数为last[i] - 1
为什么呢。。因为我自己组合数学没学好。要通过范德蒙恒等式来进行转换。。弱弱的给个链接http://blog.csdn.net/acdreamers/article/details/31032763
然后,对于阶层,很容易乘爆,而且组合数学是需要除的,所以需要用到乘法逆元,再给个链接。http://blog.csdn.net/daniel_csdn/article/details/50783734
这一道题数学知识涨得很多,很欣慰。
/* @resouces: codeforces 785D @date: 2017-3-18 @author: QuanQqqqq @algorithm: 组合数学 快速幂 前后缀和 费马小 */ #include <bits/stdc++.h> #define ll long long #define MAXN 200105 using namespace std; const ll mod = 1e9 + 7; ll fac[MAXN],nfac[MAXN]; //阶层,阶层的逆元 ll qsm(ll m,ll n){ ll ans = 1; while(n){ if(n & 1){ ans = (ans * m) % mod; } m = m * m % mod; n >>= 1; } return ans; } void init(){ fac[0] = fac[1] = 1; for(ll i = 2;i < MAXN;i++){ fac[i] = (i * 1LL * fac[i - 1]) % mod; } nfac[MAXN - 1] = qsm(fac[MAXN - 1],mod - 2) % mod; for(ll i = MAXN - 2;i >= 0;i--){ nfac[i] = (nfac[i + 1] * (i + 1)) % mod; } } ll C(ll n,ll m){ if(m == 0) return 1; return fac * nfac[n - m] % mod * nfac[m] % mod; } ll pre[MAXN],last[MAXN]; char ch[MAXN]; int main(){ init(); scanf("%s",ch + 1); int len = strlen(ch + 1); ll p = 0; for(int i = 1;i <= len;i++){ if(ch[i] == '('){ p++; } pre[i + 1] = p; } p = 0; for(int i = len;i >= 1;i--){ if(ch[i] == ')'){ p++; } last[i] = p; } ll ans = 0; for(int i = 1;i <= len;i++){ if(pre[i] && last[i] && ch[i - 1] == '('){ (ans += C(pre[i] + last[i] - 1,last[i] - 1) % mod) %= mod; } } printf("%lld\n",ans % mod); }
记一发阶层逆元的代码
void init(){ fac[0] = fac[1] = 1; for(ll i = 2;i < MAXN;i++){ fac[i] = (i * 1LL * fac[i - 1]) % mod; } nfac[MAXN - 1] = qsm(fac[MAXN - 1],mod - 2) % mod; for(ll i = MAXN - 2;i >= 0;i--){ nfac[i] = (nfac[i + 1] * (i + 1)) % mod; } }
相关文章推荐
- codeforces 785D
- Codeforces 785D 数学
- Codeforces-785D-Anton and School - 2(组合数学,范德蒙恒等式)
- 【codeforces 785D】Anton and School - 2
- CodeForces - 785D
- Codeforces 785D - Anton and School - 2(范德蒙恒等式+逆元)
- [刷题]Codeforces 785D - Anton and School - 2
- Codeforces 785D 范德蒙恒等式的变形
- Codeforces-340-C(c++)
- Codeforces 417E Square Table(随机算法)
- 【二分】Codeforces 706B Interesting drink
- Trees CodeForces - 58C 暴力
- CodeForces 280C 浅谈期望线性性的树上问题实际运用
- codeforces 126B Password - Z-Box算法
- codeforces 508B Anton and currency you all know
- CodeForces 609 C. Load Balancing(水~)
- CodeForces 508C (贪心)
- CodeForces 706 C. Hard problem(dp)
- CodeForces - 799B T-shirt buying 数据结构
- CodeForces - 725D Contest Balloons 贪心