D. Anton and School - 2
time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

As you probably know, Anton goes to school. One of the school subjects that Anton studies is Bracketology. On the Bracketology lessons students usually learn different sequences that consist of round brackets (characters "(" and ")" (without quotes)).

On the last lesson Anton learned about the regular simple bracket sequences (RSBS). A bracket sequence s of length n is an RSBS if the following conditions are met:

  • It is not empty (that is n ≠ 0).
  • The length of the sequence is even.
  • First  charactes of the sequence are equal to "(".
  • Last  charactes of the sequence are equal to ")".

For example, the sequence "((()))" is an RSBS but the sequences "((())" and "(()())" are not RSBS.

Elena Ivanovna, Anton's teacher, gave him the following task as a homework. Given a bracket sequence s. Find the number of its distinct subsequences such that they are RSBS. Note that a subsequence of s is a string that can be obtained from s by deleting some of its elements. Two subsequences are considered distinct if distinct sets of positions are deleted.

Because the answer can be very big and Anton's teacher doesn't like big numbers, she asks Anton to find the answer modulo 109 + 7.

Anton thought of this task for a very long time, but he still doesn't know how to solve it. Help Anton to solve this task and write a program that finds the answer for it!

Input

The only line of the input contains a string s — the bracket sequence given in Anton's homework. The string consists only of characters "(" and ")" (without quotes). It's guaranteed that the string is not empty and its length doesn't exceed 200 000.

Output

Output one number — the answer for the task modulo 109 + 7.

Examples
input
)(()()
output
6
input
()()()
output
7
input
)))
output
0

题目链接:CF 785D

这道题实际上就算不能过也可以是可以写一下的,就是基本会TLE……记当前位置为x,[1,x]中的左括号个数为L,[x+1,len]中右括号个数为R,可以发现每次增加一个 '(',可以跟右边组合的情况多了$$\sum_{i=0}^{min(L-1,R-1)}\binom{L-1}{i} * \binom{R}{i+1}$$

这个式子把右边的组合数又可以化成$$\sum_{i=0}^{min(L-1,R-1)}\binom{L-1}{i} * \binom{R}{R-i-1}$$,可以发现下面之和是一个常数即$R-1$,这个时候就出现了很厉害的公式——范德蒙恒等式

然后就不用每一次都for一遍把组合数加起来,而是加上组合数$$\binom{L-1+R}{R-1} $$就行。

代码:

#include <stdio.h>
#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define LC(x) (x<<1)
#define RC(x) ((x<<1)+1)
#define MID(x,y) ((x+y)>>1)
#define CLR(arr,val) memset(arr,val,sizeof(arr))
#define FAST_IO ios::sync_with_stdio(false);cin.tie(0);
typedef pair<int, int> pii;
typedef long long LL;
const double PI = acos(-1.0);
const int N = 200010;
const LL MOD = 1e9 + 7;
char s[N];
LL fac[N], inv[N];
int preL[N], preR[N]; LL qpow(LL a, LL b, LL m)
{
LL r = 1LL;
while (b)
{
if (b & 1)
r = r * a % m;
a = a * a % m;
b >>= 1;
}
return r;
}
void init()
{
fac[0] = 1LL;
inv[0] = 1LL;
for (LL i = 1; i < N; ++i)
{
fac[i] = fac[i - 1] * i % MOD;
inv[i] = qpow(fac[i], MOD - 2, MOD);
}
}
LL combine(LL n, LL m, LL mod)
{
LL ret = ((fac[n] * inv[m]) % mod * inv[n - m]) % mod;
return ret;
}
int main(void)
{
init();
int i;
while (~scanf("%s", s + 1))
{
CLR(preL, 0);
CLR(preR, 0);
int len = strlen(s + 1);
for (i = 1; i <= len; ++i)
{
preL[i] = preL[i - 1] + (s[i] == '(');
preR[i] = preR[i - 1] + (s[i] == ')');
}
LL ans = 0LL;
for (i = 1; i <= len; ++i)
{
if (s[i] == '(')
{
int rightR = preR[len] - preR[i];
ans = ans + combine(preL[i] - 1 + rightR, rightR - 1, MOD);
if (ans > MOD)
ans %= MOD;
}
}
printf("%I64d\n", ans);
}
return 0;
}

Codeforces 785D Anton and School - 2 (组合数相关公式+逆元)的更多相关文章

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

    [题目链接] http://codeforces.com/problemset/problem/785/D [题目大意] 给出一个只包含左右括号的串,请你找出这个串中的一些子序列, 要求满足" ...

  2. [刷题]Codeforces 785D - Anton and School - 2

    Description As you probably know, Anton goes to school. One of the school subjects that Anton studie ...

  3. Codeforces 785D - Anton and School - 2 - [范德蒙德恒等式][快速幂+逆元]

    题目链接:https://codeforces.com/problemset/problem/785/D 题解: 首先很好想的,如果我们预处理出每个 "(" 的左边还有 $x$ 个 ...

  4. CodeForces 785D Anton and School - 2

    枚举,容斥原理,范德蒙恒等式. 先预处理每个位置之前有多少个左括号,记为$L[i]$. 每个位置之后有多少个右括号,记为$R[i]$. 然后枚举子序列中第一个右括号的位置,计算这个括号的第一个右括号的 ...

  5. CodeForces 785D Anton and School - 2 (组合数学)

    题意:有一个只有’(‘和’)’的串,可以随意的删除随意多个位置的符号,现在问能构成((((((…((()))))….))))))这种对称的情况有多少种,保证中间对称,左边为’(‘右边为’)’. 析:通 ...

  6. Codeforces 785D Anton and School - 2(推公式+乘法原理+组合数学)

    题目链接 Anton and School - 2 对于序列中的任意一个单括号对(), 左括号左边(不含本身)有a个左括号,右括号右边(不含本身有)b个右括号. 那么答案就为 但是这样枚举左右的()的 ...

  7. HDU 4704 Sum(隔板原理+组合数求和公式+费马小定理+快速幂)

    题目传送:http://acm.hdu.edu.cn/showproblem.php?pid=4704 Problem Description   Sample Input 2 Sample Outp ...

  8. 【codeforces 785D】Anton and School - 2

    [题目链接]:http://codeforces.com/contest/785/problem/D [题意] 给你一个长度为n的括号序列; 让你删掉若干个括号之后,整个序列变成前x个括号为左括号,后 ...

  9. Anton and School - 2 CodeForces - 785D (组合计数,括号匹配)

    大意: 给定括号字符串, 求多少个子序列是RSGS. RSGS定义如下: It is not empty (that is n ≠ 0). The length of the sequence is ...

随机推荐

  1. 【洛谷1967】货车运输(最大生成树+倍增LCA)

    点此看题面 大致题意: 有\(n\)个城市和\(m\)条道路,每条道路有一个限重.多组询问,每次询问从\(x\)到\(y\)的最大载重为多少. 一个贪心的想法 首先,让我们来贪心一波. 由于要求最大载 ...

  2. Ribbon 负载均衡搭建

    本机IP为  192.168.1.102 1.   新建Maven  项目    ribbon 2.   pom.xml <project xmlns="http://maven.ap ...

  3. 黑马基础阶段测试题:创建Phone(手机)类,Phone类中包含以下内容:

    package com.swift; public class Phone { private String pinpai; private int dianliang; public String ...

  4. java算法面试题:有数组a[n],用java代码将数组元素顺序颠倒

    package com.swift; import java.util.ArrayList; import java.util.Collections; import java.util.List; ...

  5. Mysql操作方法类

    帮助类: using System; using System.Collections.Generic; using System.Data; using System.Linq; using Sys ...

  6. 四、MySQL 连接

    MySQL 连接 使用mysql二进制方式连接 您可以使用MySQL二进制方式进入到mysql命令提示符下来连接MySQL数据库. 实例 以下是从命令行中连接mysql服务器的简单实例: [root@ ...

  7. CSS+JS实现流星雨动画

    引言 平常会做一些有意思的小案例练手,通常都会发到codepen上,但是codepen不能写分析.        所以就在博客上开个案例分享系列,对demo做个剖析.目的以分享为主,然后也希望各路大神 ...

  8. Python知识点入门笔记——基本控制流程

    复合赋值语句 在Python中,可以使用一次赋值符号,给多个变量同时赋值:                  划重点:age_1,age_2 = age_2,age_1这种操作是Python独有的 i ...

  9. HashTable, HashMap,TreeMap区别

    java为数据结构中的映射定义了一个接口java.util.Map,而HashMap Hashtable和TreeMap就是它的实现类.Map是将键映射到值的对象,一个映射不能包含重复的键:每个键最多 ...

  10. python-PIL模块的使用

    PIL基本功能介绍 from PIL import Image from PIL import ImageEnhance img = Image.open(r'E:\img\f1.png') img. ...