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

bzoj 1856 [SCOI2010]生成字符串

时间:2018-10-05 15:04:13      阅读:119      评论:0      收藏:0      [点我收藏+]

标签:printf   pac   数字   str   mod   void   bzoj   等于   答案   

题目大意:给你n个1和m个0,你要用这些数字组成一个长度为n+m的串,对于任意一个位置k,要保证前k个数字中1的数量大于等于0的数量,求所有合法的串的数量

答案转化为所有方案数-不合法方案数

所有方案数显然是技术分享图片

现在比较易懂的解法是转化进坐标系

从(0,0)开始,填1视为向右上↗走,填0视为向右下↘走,如果路径经过了y=-1这条直线,说明不合法

把一个经过y=-1的路径的左半部分(即在路径和y=-1交点之前的那部分路径)关于y=-1翻转

因为是从(0,0)出发,现在变成了从(0,-2)出发,求方案数,显然是技术分享图片

所以最终答案是技术分享图片

求逆元即可

 1 #include <queue>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 #define N 2000100
 6 #define mod 20100403
 7 #define ll long long 
 8 using namespace std;
 9 
10 int n,m;
11 ll mu[N],inv[N];
12 
13 void get_mu()
14 {
15     mu[0]=mu[1]=inv[0]=inv[1]=1;
16     for(ll i=2;i<=n+m;i++)
17         mu[i]=mu[i-1]*i%mod,
18         inv[i]=(mod-mod/i)*inv[mod%i]%mod;
19     for(ll i=2;i<=n+m;i++)
20         inv[i]=inv[i]*inv[i-1]%mod;
21 }
22 
23 int main()
24 {
25     scanf("%d%d",&n,&m);
26     get_mu();
27     ll ans1=mu[n+m]*inv[n]%mod*inv[m]%mod;
28     ll ans2=mu[n+m]*inv[n+1]%mod*inv[m-1]%mod;
29     printf("%lld\n",(ans1-ans2+mod)%mod);
30     return 0;
31 }

 

bzoj 1856 [SCOI2010]生成字符串

标签:printf   pac   数字   str   mod   void   bzoj   等于   答案   

原文地址:https://www.cnblogs.com/guapisolo/p/9744645.html

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