codeforces 785D D. Anton and School - 2

题目链接:http://codeforces.com/problemset/problem/785/D

题意:给你一个只包含‘(‘和‘)‘的字符串,然后问他的子序列中有多少满足前一半是左括号,后一半是右括号。

分析:看到题就想到是组合数学,对于一个左括号,他能影响到的右括号就是他后边的,因此,你需要求前缀和和后缀和,来这样来求组合数。现在我们枚举左括号,当枚举到他时,代表他一定被选,前缀和为n,后缀和为m,然后在他前边选i=0到min(n,m)-1个,在他后边选前边数+1个。然后就是C(n-1,i)*C(m,i+1) ,也就是C(n-1,i)+C(m,m-i-1);求和即为C(n+m-1,m-1),然后用卢卡斯定理求即可,注意存n!还有求逆元。

AC代码:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3
 4 long long mod=1e9+7;
 5 char s[200005];
 6 int a[200005];
 7 int b[200005];
 8 long long num[200005];
 9 long long qpow(long long x,long long n){
10     if(n==0) return 1;
11     long long ans=1;
12     x=x%mod;
13     while(n!=0){
14         if(n&1) {
15             ans=ans*x%mod;
16         }
17         x=x*x%mod;
18         n=n/2;
19     }
20     return ans;
21 }
22 long long Cn(long long n,long long m){
23     if(n<m) return 0;
24     if(n==m) return 1;
25     if(m>n-m) m=n-m;
26
27     return (num[n]*qpow(num[n-m]*num[m],mod-2))%mod;
28 }
29
30 int main(){
31     ios_base::sync_with_stdio(0);
32     cin.tie(0);
33     num[0]=1;
34     for(long long i=1;i<=200000;i++){
35         num[i]=num[i-1]*i%mod;
36     }
37     cin>>s;
38     int d=strlen(s);
39     int num1=0,num2=0;
40     for(int i=0;i<d;i++){
41         if(s[i]==‘(‘){
42             num1++;
43         }
44         a[i]=num1;
45     }
46     for(int i=d-1;i>=0;i--){
47         if(s[i]==‘)‘){
48             num2++;
49         }
50         b[i]=num2;
51     }
52     long long result=0;
53     for(int i=0;i<d;i++){
54         if(s[i]==‘(‘){
55            result=(result+Cn(a[i]+b[i]-1,b[i]-1))%mod;
56         //cout<<result<<endl;
57         }
58     }
59     cout<<result<<endl;
60     return 0;
61 }

时间: 2024-12-17 01:20:23

codeforces 785D D. Anton and School - 2的相关文章

Codeforces 785 E. Anton and Permutation(分块,树状数组)

Codeforces 785 E. Anton and Permutation 题目大意:给出n,q.n代表有一个元素从1到n的数组(对应索引1~n),q表示有q个查询.每次查询给出两个数l,r,要求将索引为l,r的两个数交换位置,并给出交换后数组中的逆序对数. 思路:此题用到了分块的思想,即将这组数分为bsz块,在每一块上建Fenwick树,对于每次查询,只需要处理l,r中间的块和l,r所在块受影响的部分.具体实现见代码及注释. #include<iostream> #include<

CodeForces 785D Anton and School - 2

枚举,容斥原理,范德蒙恒等式. 先预处理每个位置之前有多少个左括号,记为$L[i]$. 每个位置之后有多少个右括号,记为$R[i]$. 然后枚举子序列中第一个右括号的位置,计算这个括号的第一个右括号的方案数. 即在它左边取$k$个左括号,在右边取$k-1$个右括号都是合法的方案,这个东西可以用范德蒙恒等式化成一个组合数以及容斥原理计算. 范德蒙恒等式:http://blog.csdn.net/acdreamers/article/details/31032763 #include <cstdio

CodeForces 785D Anton and School - 2 组合数学

题意: 给你一串括号 问你有多少种匹配的子串 就是前半部分都是'(' 后半部分都是')'的子串 思路: 首先我们预处理 当前位置之前有多少左括号 和 当前位置之后有多少右括号 对于每一个处于i位置的左括号 我们将ans+=C(left[i]+right[i]-1,right[i]-1) 这个式子是C(i-1,left[i]-1)*C(i+1,right[i])化简来的 因为选的数总数是不变的 所以可以化简(?) 就是从左边选i-1个左括号 从右边选i+1个右括号 因为自己是必选的 所以左括号-1

CodeForces 785 D Anton and School - 2 范德蒙恒等式

Anton and School - 2 题解: 枚举每个左括号作为必选的. 那么方案数就应该是下面的 1 , 然后不断化简, 通过范德蒙恒等式 , 可以将其化为一个组合数. 代码: #include<bits/stdc++.h> using namespace std; #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdou

Codeforces Round #253 (Div. 2) A. Anton and Letters

题目很简单,只需要注意带空格的输入用getline即可 #include <iostream> #include <vector> #include <algorithm> #include <string> #include <set> using namespace std; int main(){ string str; getline(cin,str); set<char> a; for(int i= 1 ; i < s

Codeforces Round #329 (Div. 2)B. Anton and Lines 贪心

B. Anton and Lines The teacher gave Anton a large geometry homework, but he didn't do it (as usual) as he participated in a regular round on Codeforces. In the task he was given a set of n lines defined by the equations y = ki·x + bi. It was necessar

codeforces 785C Anton and Fairy Tale

题目链接:http://codeforces.com/problemset/problem/785/C 题意:仓库容量是n,一开始是满的,然后每天晚上可以往仓库里装m粮食,最多装到n.然后每天白天有鸟来吃粮食,一只鸟吃1单位.第i天有i只鸟.问你多少天鸟可以把粮食吃完. 分析:一开始读错题,导致wa了两发.如果n<=m的话,只有n只鸟的时候一天把他吃完,输出n.如果m<n的话,前m是肯定吃不完的,m天之后,从1开始计数,就是好比每天白天吃i+m,晚上装m,一天好比加了i.所以可以二分天数,但是

Codeforces Round #379 (Div. 2) C. Anton and Making Potions(二分)

Anton is playing a very interesting computer game, but now he is stuck at one of the levels. To pass to the next level he has to prepare npotions. Anton has a special kettle, that can prepare one potions in x seconds. Also, he knows spells of two typ

Codeforces Round #379 (Div. 2) D. Anton and Chess(模拟)

Anton likes to play chess. Also, he likes to do programming. That is why he decided to write the program that plays chess. However, he finds the game on 8 to 8 board to too simple, he uses an infinite one instead. The first task he faced is to check