Codeforces Round #404 (Div. 2) ---d

D. Anton and School - 2

这题第一眼一直觉得是dp,然而到最后他竟然是个数学题2333

考虑暴力,我们枚举一个‘(‘,来求选他的情况下方案数有多少,那么事实上我们就是要在该位置左边选取i个‘(‘,在其右边选取i+1个‘)‘,可以保证不重不漏。暴力的话On统计即可。那么就是要化简组合数的求和。即C(n,i)*C(m,i+1) (0<=i<=min(n,m-1))

我们发现C(m,i+1)=C(m,m-i-1)

而i+(m-i-1)是定值。

也就是说变成了现在前n个数中选i个,再在后m个数中选m-1-i个,那么这其实等价于在这n+m个数字中一次性选出m-1个。

那么答案就是C(m+n,m-1),On扫一遍并计算组合数即可。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int mod=1e9+7;
 4 const int inf=2e5+10;
 5 int fast(int x,int y){
 6     int ans=1;
 7     while(y){
 8         if(y&1)ans=1ll*ans*x%mod;
 9         x=1ll*x*x%mod;
10         y>>=1;
11     }
12     return ans;
13 }
14 int fac[inf];
15 int C(int x,int y){
16     return 1ll*fac[x]*fast(fac[y],mod-2)%mod*fast(fac[x-y],mod-2)%mod;
17 }
18 int n,ans;
19 char s[inf];
20 int s1[inf],s2[inf];
21 int main()
22 {
23     scanf("%s",s+1);
24     n=strlen(s+1);
25     fac[0]=1;
26     for(int i=1;i<=n;i++)
27         fac[i]=1ll*fac[i-1]*i%mod;
28     for(int i=1;i<=n;i++)
29         s1[i]=s1[i-1]+(s[i]==‘(‘);
30     for(int i=n;i>=1;i--)
31         s2[i]=s2[i+1]+(s[i]==‘)‘);
32     for(int i=1;i<=n;i++)
33         if(s[i]==‘(‘){
34             ans+=C(s1[i-1]+s2[i+1],s2[i+1]-1);
35             ans%=mod;
36         }
37     printf("%d\n",ans);
38     return 0;
39 }

事实上这个就是"范德蒙恒等式"

原文地址:https://www.cnblogs.com/hyghb/p/8505451.html

时间: 2024-07-29 23:49:07

Codeforces Round #404 (Div. 2) ---d的相关文章

Codeforces Round #404 (Div. 2) C 二分,水 D 数学,好题 E 分块

Codeforces Round #404 (Div. 2) C. Anton and Fairy Tale 题意:仓库容量n,每天运来m粮食,第 i 天被吃 i 粮食,问第几天仓库第一次空掉. tags:==SB题 注:二分边界判断,数据范围爆long long判断. // CF404 C #include<bits/stdc++.h> using namespace std; #pragma comment(linker, "/STACK:102400000,102400000&

Codeforces Round #404 (Div. 2) C 二分查找

Codeforces Round #404 (Div. 2) 题意:对于 n and m (1?≤?n,?m?≤?10^18)  找到 1) [n<= m] cout<<n; 2) [n>m]最小的 k => (k -m) * (k-m+1) >= (n-m)*2 成立 思路:二分搜索 #include <bits/stdc++.h> #include <map> using namespace std; #define LL long long

Codeforces Round #404 (Div. 2)

A: Anton and Polyhedrons(水题) B: Anton and Classes(水题) C: Anton and Fairy Tale(二分) 思路:m>=n时 ans=n;m<n时 前m天都能补满,第m+1天时就要开始减少了,n-m-(x+1)*x/2是m天后第x天的剩余,二分n-m<=x*(x+1)/2的最小的x,ans=m+x; D: Anton and School - 2(组合计数) 思路:枚举左括号的最后一个,它之前有n个左括号,右边有m个有括号,那么就C

【Codeforces Round #404 (Div. 2)】题解

A. Anton and Polyhedrons 直接统计+答案就可以了. #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #define maxn 1000 #define LL long long using namespace std; char s[10000]; int main() { int n; LL sum=0; scanf("%d&qu

Codeforces Round #404 (Div. 2)——ABCDE

题目这里 A.map裸题 #include <bits/stdc++.h> using namespace std; map <string, int> p; string s[] = { "Tetrahedron", "Cube", "Octahedron" , "Dodecahedron", "Icosahedron" }; int ss[] = {4, 6, 8, 12, 20

Codeforces Round #279 (Div. 2) ABCD

Codeforces Round #279 (Div. 2) 做得我都变绿了! Problems # Name     A Team Olympiad standard input/output 1 s, 256 MB  x2377 B Queue standard input/output 2 s, 256 MB  x1250 C Hacking Cypher standard input/output 1 s, 256 MB  x740 D Chocolate standard input/

Codeforces Round #428 (Div. 2)

Codeforces Round #428 (Div. 2) A    看懂题目意思就知道做了 #include<bits/stdc++.h> using namespace std; #pragma comment(linker, "/STACK:102400000,102400000") #define rep(i,a,b) for (int i=a; i<=b; ++i) #define per(i,b,a) for (int i=b; i>=a; --i

Codeforces Round #424 (Div. 2) D. Office Keys(dp)

题目链接:Codeforces Round #424 (Div. 2) D. Office Keys 题意: 在一条轴上有n个人,和m个钥匙,门在s位置. 现在每个人走单位距离需要单位时间. 每个钥匙只能被一个人拿. 求全部的人拿到钥匙并且走到门的最短时间. 题解: 显然没有交叉的情况,因为如果交叉的话可能不是最优解. 然后考虑dp[i][j]表示第i个人拿了第j把钥匙,然后 dp[i][j]=max(val(i,j),min(dp[i-1][i-1~j]))   val(i,j)表示第i个人拿

Codeforces Round #424 (Div. 2) C. Jury Marks(乱搞)

题目链接:Codeforces Round #424 (Div. 2) C. Jury Marks 题意: 给你一个有n个数序列,现在让你确定一个x,使得x通过挨着加这个序列的每一个数能出现所有给出的k个数. 问合法的x有多少个.题目保证这k个数完全不同. 题解: 显然,要将这n个数求一下前缀和,并且排一下序,这样,能出现的数就可以表示为x+a,x+b,x+c了. 这里 x+a,x+b,x+c是递增的.这里我把这个序列叫做A序列 然后对于给出的k个数,我们也排一下序,这里我把它叫做B序列,如果我