码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2018-03-04 19:08:24      阅读:88      评论:0      收藏:0      [点我收藏+]

标签:mod   style   lan   等价   一个   class   img   枚举   现在   

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 }
View Code

 

 

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

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

标签:mod   style   lan   等价   一个   class   img   枚举   现在   

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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!