cf785D(组合数学)
题目链接: http://codeforces.com/problemset/problem/785/D
题意: 左边全为 '(' 右边全为 ')' 且两者数量想等的字符串称为 RSBS. 给出一个由 '(' 和 ')' 组成的字符串, 问其有多少子序列是 RSBS.
思路: 可以先预处理一下, 用 a[i] 记录 i 前面(包括 i 这个位置)的 '(' 的数目, b[i] 记录 i 后面(包括 i 这个位置)的 ')' 的数目, 然后从左往右枚举以 '(' 结尾的情况,
那么当前情况下的 RSBS 数目为:
C(a[i] - 1, 0) * C(b[i], 1) + C(a[i] - 1, 1) * C(b[i], 2) + C(a[i] - 1, 2) * C(b[i], 3) + ...
= ∑min(a-1, b-1)0 C(a - 1, x) * C(b, x + 1)
= ∑min(a-1, b-1)0 C(a - 1, a - 1 - x) * C(b, x + 1)
= C(a - 1 + b, a) (范德蒙恒等式)
然后将所有情况的 RSBS 数目累加一下就好啦.
注意这里的组合数比较大, 取模的话需要用到 exgcd 或者 快速幂.
代码1: 快速幂求组合数取模 C(n, m) % mode = (n! % mode) * get_pow((n - m)! * m! % mode, mode - 2) % mode. (这个公式能通过费马小定理变换得到).
#include <iostream>
#define ll long long
using namespace std; const int mode = 1e9 + ;
const int MAXN = 2e5 + ;
ll a[MAXN], b[MAXN], gel[MAXN];
string s; ll get_pow(ll x, int n){
ll ans = ;
while(n){
if(n & ) ans = ans * x % mode;
x = x * x % mode;
n >>= ;
}
return ans;
} int main(void){
ll ans = ;
cin >> s;
if(s[] == '(') a[] = ;
for(int i = ; i < s.size(); i++){
if(s[i] == '(') a[i] = a[i - ] + ;
else a[i] = a[i - ];
}
for(int i = s.size() - ; i >= ; i--){
if(s[i] == ')') b[i] = b[i + ] + ;
else b[i] = b[i + ];
}
gel[] = ;
for(int i = ; i < MAXN; i++){
gel[i] = gel[i - ] * i % mode;
}
for(int i = ; i < s.size(); i++){
if(s[i] == ')') continue;
ll cnt1 = a[i], cnt2 = a[i] + b[i] - ;
ans = (ans + (gel[cnt2] * get_pow(gel[cnt1] * gel[cnt2 - cnt1] % mode, mode - )) % mode) % mode;
}
cout << ans << endl;
return ;
}
代码2: 用乘法逆元求得组合数取模
#include <iostream>
#define ll long long
using namespace std; const int mode = 1e9 + ;
const int MAXN = 2e5 + ;
ll a[MAXN], b[MAXN], gel[MAXN];
string s; void exgcd(ll a, ll b, ll &x, ll &y){
if(!b){
y = ;
x = ;
return;
}
exgcd(b, a % b, y, x);
y -= a / b * x;
} int main(void){
ll ans = ;
cin >> s;
if(s[] == '(') a[] = ;
for(int i = ; i < s.size(); i++){
if(s[i] == '(') a[i] = a[i - ] + ;
else a[i] = a[i - ];
}
for(int i = s.size() - ; i >= ; i--){
if(s[i] == ')') b[i] = b[i + ] + ;
else b[i] = b[i + ];
}
gel[] = ;
for(int i = ; i < MAXN; i++){
gel[i] = gel[i - ] * i % mode;
}
for(int i = ; i < s.size(); i++){
if(s[i] == ')') continue;
ll cnt1 = a[i], cnt2 = a[i] + b[i] - ;
ll cc1 = gel[cnt2], cc2 = gel[cnt2 - cnt1] * gel[cnt1] % mode;
ll x, y;
exgcd(cc2, mode, x, y);
x = (x % mode + mode) % mode;
ans = (ans + (cc1 * x) % mode) % mode; }
cout << ans << endl;
return ;
}
cf785D(组合数学)的更多相关文章
- poj 3734 Blocks 快速幂+费马小定理+组合数学
题目链接 题意:有一排砖,可以染红蓝绿黄四种不同的颜色,要求红和绿两种颜色砖的个数都是偶数,问一共有多少种方案,结果对10007取余. 题解:刚看这道题第一感觉是组合数学,正向推了一会还没等推出来队友 ...
- 组合数学or not ---- n选k有重
模板问题: 1. 取物品 (comb.pas/c/cpp) [问题描述] 现在有n个物品(有可能相同),请您编程计算从中取k个有多少种不同的取法.[输入] 输入文件有两行,第一行包含两个整数n,k(2 ...
- 组合数学(全排列)+DFS CSU 1563 Lexicography
题目传送门 /* 题意:求第K个全排列 组合数学:首先,使用next_permutation 函数会超时,思路应该转变, 摘抄网上的解法如下: 假设第一位是a,不论a是什么数,axxxxxxxx一共有 ...
- uestc1888 Birthday Party 组合数学,乘法原理
题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=25539#problem/G 题目意思: 有n个人,每个人有一个礼物,每个人能拿 ...
- UVA 11076 Add Again 计算对答案的贡献+组合数学
A pair of numbers has a unique LCM but a single number can be the LCM of more than one possiblepairs ...
- POJ3252——Round Number(组合数学)
Round Numbers DescriptionThe cows, as you know, have no fingers or thumbs and thus are unable to pla ...
- HDU4675【GCD of scequence】【组合数学、费马小定理、取模】
看题解一开始还有地方不理解,果然是我的组合数学思维比较差 然后理解了之后自己敲了一个果断TLE.... 我以后果然还得多练啊 好巧妙的思路啊 知识1: 对于除法取模还需要用到费马小定理: a ^ (p ...
- hdu 4810 Wall Painting (组合数学+二进制)
题目链接 下午比赛的时候没有想出来,其实就是int型的数分为30个位,然后按照位来排列枚举. 题意:求n个数里面,取i个数异或的所有组合的和,i取1~n 分析: 将n个数拆成30位2进制,由于每个二进 ...
- CCF 201312-4 有趣的数 (数位DP, 状压DP, 组合数学+暴力枚举, 推公式, 矩阵快速幂)
问题描述 我们把一个数称为有趣的,当且仅当: 1. 它的数字只包含0, 1, 2, 3,且这四个数字都出现过至少一次. 2. 所有的0都出现在所有的1之前,而所有的2都出现在所有的3之前. 3. 最高 ...
随机推荐
- 原生js图片懒加载特效
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- python基础-变量
1.什么是变量? 其实就是给数据起个名字而已.在python中你不想要关心数据类型,因为在你赋值的时候它已经自己帮你识别了 2.创建变量时候会在内存中开辟一个空间,具体的细节不需要咱们关心,解释器会分 ...
- JSP分页1
分页 1.什么分页? 第N页/共M页 首页 上一页 1 2 3 4 5 6 7 8 9 10 下一页 尾页 口 go 分页的优点:只查询一页,不用查询所有页! 2.分页数据 页面的数据都是由Servl ...
- leetcode 226. Invert Binary Tree(递归)
Invert a binary tree. 4 / \ 2 7 / \ / \ 1 3 6 9 to 4 / \ 7 2 / \ / \ 9 6 3 1 Trivia:This problem was ...
- 【leetcode刷题笔记】Roman to Integer
Given a roman numeral, convert it to an integer. Input is guaranteed to be within the range from 1 t ...
- Git 部署 Web 网站
/*************************************************************************** * Git 部署 Web 网站 * 说明: * ...
- 2016北京集训 小Q与进位制
题目大意 一个数每一位进制不同,已知每一位的进制,求该数的十进制表达. 显然有 $$Ans=\sum\limits_{i=0}^{n-1}a_i \prod\limits_{j=0}^{i-1}bas ...
- IronPython for ASP.NET 部署注意事项
用 IronPython for ASP.NET 开发的网站,在部署时,除了发布 bin 目录下的 IronPython.dll, IronMath.dll, Microsoft.Web.IronPy ...
- 标准模板库(STL)学习指南之sort排序
对于程序员来说,数据结构是必修的一门课.从查找到排序,从链表到二叉树,几乎所有的算法和原理都需要理解,理解不了也要死记硬背下来.幸运的是这些理论都已经比较成熟,算法也基本固定下来,不需要你再去花费心思 ...
- poj 1637 Sightseeing tour —— 最大流+欧拉回路
题目:http://poj.org/problem?id=1637 建图很妙: 先给无向边随便定向,这样会有一些点的入度不等于出度: 如果入度和出度的差值不是偶数,也就是说这个点的总度数是奇数,那么一 ...