一、题目

点此看题

二、解法

前置芝士:范德蒙德卷积:
C(n+m,k)=∑i=0kC(n,i)C(m,k−i)C(n+m,k)=\sum_{i=0}^kC(n,i)C(m,k-i)C(n+m,k)=i=0∑k​C(n,i)C(m,k−i)这道题的暴力算式是很好写的,但是优化不动,因为用不到a−b≤10000a-b\leq10000a−b≤10000,从最简单的情况考虑:

部分分:a=b

此时a,ba,ba,b公平竞争,对于aaa赢着的情况,一定严格对应一种aaa输着的情况(把他们的输赢情况反转),那么我们考虑算出他们平局的情况,用所有情况减去除222即是答案,平局算式如下:
∑i=0aC(a,i)2=∑i=0aC(a,i)C(a,a−i)=C(2a,a)\sum_{i=0}^aC(a,i)^2=\sum_{i=0}^aC(a,i)C(a,a-i)=C(2a,a)i=0∑a​C(a,i)2=i=0∑a​C(a,i)C(a,a−i)=C(2a,a)所以答案是:
2a+b−C(2a,a)2\frac{2^{a+b}-C(2a,a)}{2}22a+b−C(2a,a)​a>b

有点难,按照部分分的对应法则我们发现有些aaa赢的情况反转时候还是赢的,我们称这种现象叫不对称,记对称的方案数是S1S_1S1​,不对称的方案数是S2S_2S2​,则有这样的关系:
S1+S2=2a+b,ans=S12+S2S_1+S_2=2^{a+b},ans=\frac{S_1}{2}+S_2S1​+S2​=2a+b,ans=2S1​​+S2​我们只需要求出其中一个就行了,求对称的只能暴力,所以我们去算S2S_2S2​,我们考虑此时满足什么样的关系,用形式上的表达,记∣a∣|a|∣a∣是aaa的111个数,∣b∣|b|∣b∣是bbb的111个数:
∣a∣>∣b∣,a−∣a∣>b−∣b∣|a|>|b|,a-|a|>b-|b|∣a∣>∣b∣,a−∣a∣>b−∣b∣也就是a−b>∣a∣−∣b∣a-b>|a|-|b|a−b>∣a∣−∣b∣,这时候出现了a−ba-ba−b就很舒服了,盯准它,枚举∣b∣|b|∣b∣和∣a∣−∣b∣|a|-|b|∣a∣−∣b∣:
S2=∑i=0bC(b,i)∑j=1a−b−1C(a,i+j)S_2=\sum_{i=0}^bC(b,i)\sum_{j=1}^{a-b-1}C(a,i+j)S2​=i=0∑b​C(b,i)j=1∑a−b−1​C(a,i+j)∑j=1a−b−1∑i=0bC(b,b−i)C(a,i+j)\sum_{j=1}^{a-b-1}\sum_{i=0}^bC(b,b-i)C(a,i+j)j=1∑a−b−1​i=0∑b​C(b,b−i)C(a,i+j)∑j=1a−b−1C(a+b,b+j)\sum_{j=1}^{a-b-1}C(a+b,b+j)j=1∑a−b−1​C(a+b,b+j)然后用算出上式这道题就结束了,模数其实是1e91e91e9,非质数,考虑扩展卢卡斯,109=295910^9=2^95^9109=2959,对两个质数次幂做卢卡斯然后crt\tt crtcrt合并就行了,需要预处理对于质因子222和555的阶乘,算卢卡斯就可以O(log⁡2)O(\log^2)O(log2)了(需要快速幂)

还有问题,最后的除222怎么解决,222的次幂可以直接搞指数,对于我们算的组合数由于是杨辉三角上的111行,具有其对称性,只用算一边就可以了,而如果a+ba+ba+b是偶数C(a+b,(a+b)/2)C(a+b,(a+b)/2)C(a+b,(a+b)/2)没有配对的,把他化到上一行变成C(a+b−1,(a+b)/2)C(a+b-1,(a+b)/2)C(a+b−1,(a+b)/2)就行了。还有一种方法就是把模数变成2e92e92e9最后就可以直接除222了。

#include <cstdio>
const int p = 1e9;
#define int long long
int read()
{int num=0,flag=1;char c;while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;while(c>='0'&&c<='9')num=(num<<3)+(num<<1)+(c^48),c=getchar();return num*flag;
}
int n,m,a,b,k,y[20],mod[2]={512,1953125},bs[2]={2,5},fac[2][2000000];
void exgcd(int a,int b,int &x,int &y)
{if(!b){x=1;y=0;return ;}exgcd(b,a%b,y,x);y-=x*(a/b);
}
int inv(int v,int p)
{int x,y;exgcd(v,p,x,y);return (x%p+p)%p;
}
int qkpow(int a,int b,int p)
{int r=1;while(b>0){if(b&1) r=r*a%p;a=a*a%p;b>>=1;}return r;
}
int fuck(int n,int t)
{if(!n) return 1;return qkpow(fac[t][mod[t]-1],n/mod[t],mod[t])*fac[t][n%mod[t]]%mod[t]*fuck(n/bs[t],t)%mod[t];
}
int L(int n,int m,int t)
{int ind=0;for(int i=n;i;i/=bs[t]) ind+=i/bs[t];for(int i=m;i;i/=bs[t]) ind-=i/bs[t];for(int i=n-m;i;i/=bs[t]) ind-=i/bs[t];if(ind>=9) return 0;int x=fuck(n,t),y=fuck(m,t),z=fuck(n-m,t);return x*inv(y,mod[t])%mod[t]*inv(z,mod[t])%mod[t]*qkpow(bs[t],ind,mod[t])%mod[t];
}
void pr(int x)
{for(int i=1;i<=k;i++,x/=10) y[i]=x%10;for(int i=k;i>=1;i--) printf("%lld",y[i]);puts("");
}
signed main()
{fac[0][0]=fac[1][0]=1;for(int i=1;i<mod[0];i++)fac[0][i]=(i%2)?i*fac[0][i-1]%mod[0]:fac[0][i-1];for(int i=1;i<mod[1];i++)fac[1][i]=(i%5)?i*fac[1][i-1]%mod[1]:fac[1][i-1];while(~scanf("%lld %lld %lld",&a,&b,&k)){int r2=0,r5=0;if(a==b)//求C(2a,a) {r2=L(2*a-1,a,0);r5=L(2*a-1,a,1);r2=r2*mod[1]%p*inv(mod[1],mod[0])%p;r2=(r2+r5*mod[0]%p*inv(mod[0],mod[1])%p)%p;pr((qkpow(2,a+b-1,p)-r2+p)%p);}else{if((a+b)%2)//对称,算一边 {for(int i=b+1;i<=(a+b)/2;i++) r2=(r2+L(a+b,i,0))%p;for(int i=b+1;i<=(a+b)/2;i++) r5=(r5+L(a+b,i,1))%p;r2=r2*mod[1]%p*inv(mod[1],mod[0])%p;r2=(r2+r5*mod[0]%p*inv(mod[0],mod[1])%p)%p;pr((qkpow(2,a+b-1,p)+r2)%p);}else//单独算C(a+b,(a+b)/2) {for(int i=b+1;i<(a+b)/2;i++) r2=(r2+L(a+b,i,0))%p;r2=(r2+L(a+b-1,(a+b)/2,0))%p;for(int i=b+1;i<(a+b)/2;i++) r5=(r5+L(a+b,i,1))%p;r5=(r5+L(a+b-1,(a+b)/2,1))%p;r2=r2*mod[1]%p*inv(mod[1],mod[0])%p;r2=(r2+r5*mod[0]%p*inv(mod[0],mod[1])%p)%p;pr((qkpow(2,a+b-1,p)+r2)%p);}}}
}

[AH2017/HNOI2017]抛硬币相关推荐

  1. bzoj 4830: [Hnoi2017]抛硬币 [范德蒙德卷积 扩展lucas]

    4830: [Hnoi2017]抛硬币 题意:A投a次硬币,B投b次硬币,a比b正面朝上次数多的方案数,模\(10^k\). \(b \le a \le b+10000 \le 10^{15}, k ...

  2. bzoj4830 hnoi2017 抛硬币

    题目描述 小 A 和小 B 是一对好朋友,他们经常一起愉快的玩耍.最近小 B 沉迷于**师手游,天天刷本,根本无心搞学习.但是已经入坑了几个月,却一次都没有抽到 SSR,让他非常怀疑人生.勤勉的小 A ...

  3. 【扩展lucas】LOJ#2023. 「AHOI / HNOI2017」抛硬币

    Description 抛硬币,小A投 a a a次,小B投 b b b次,求小A正面次数多于小B正面次数的方案数. 1 ≤ a , b ≤ 1 e 15 , 0 ≤ a − b ≤ 1 e 4 , ...

  4. (每日一题)P3723 [AH2017/HNOI2017]礼物(经典FFT)

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 每日一题(莫反 / 多项式 / 母函数 / 群论) 2021.4.15 多项式 FFT Problem ...

  5. 有道概率题:一个有趣的抛硬币问题

    假设有一个硬币,抛出字(背面)和花(正面)的概率都是0.5,而且每次抛硬币与前次结果无关.现在做一个游戏,连续地抛这个硬币,直到连续出现两次字为止,问平均要抛多少次才能结束游戏?注意,一旦连续抛出两个 ...

  6. 抛硬币直到若干次(k次)连续正面向上的概率

    文章目录 问题描述 说明 解答过程 问题描述 问题描述:抛一枚硬币,当出现连续的三次(或k次)正面向上的时候停止,问抛硬币的次数期望是多少? 说明 这个问题网上有很多答案,解释都不清楚,很多解释都误导 ...

  7. 抛硬币 直到连续出现两次字为止

    题目: [plain] view plaincopy 假设有一个硬币,抛出字(背面)和花(正面)的概率都是0.5,而且每次抛硬币与前次结果无关.现在做一个游戏,连续地抛这个硬币,直到连续出现两次字为止 ...

  8. boost::math模块二项式分布来预测概率 抛硬币时的正面和反面的测试程序

    boost::math模块二项式分布来预测概率 抛硬币时的正面和反面的测试程序 实现功能 C++实现代码 实现功能 boost::math模块二项式分布来预测概率 抛硬币时的正面和反面的测试程序 C+ ...

  9. Java黑皮书课后题第5章:5.40(模拟:正面或反面)编写程序,模拟抛硬币一百万次,显示出现正面和反面的次数

    5.40(模拟:正面或反面)编写程序,模拟抛硬币一百万次,显示出现正面和反面的次数 题目 题目概述 破题 代码 运行示例 题目 题目概述 5.40(模拟:正面或反面)编写程序,模拟抛硬币一百万次,显示 ...

最新文章

  1. android+图标闪烁动画,如何在android中闪烁通知图标? [DONE]
  2. mysql 8.0什么时候发布_MySQL 8.0.22正式发布
  3. C++ 使用dynamic_cast执行基类向派生类的转换
  4. 访问Storm ui界面,出现Nimbus Summary或Supervisor Summary时有时无的问题解决(图文详解)...
  5. vue 时间插件_Vue3 插件开发详解尝鲜版「值得收藏」
  6. 导入导出 Oracle 分区表数据
  7. oracle语法官方文档,Oracle官方文档必备语法知识
  8. android filehelper,为AndroidStudio开发mvp插件(MvpHelper)
  9. olcd12864的u8g2库_Arduino为什么无法用u8g2驱动12864OLED屏?求找出错误
  10. Linux下的时间戳
  11. MySql 1248 - Every derived table must have its own alias
  12. 异常 未解决 dubbo 打包 使用将所有的文件打在一个包内 会报错误
  13. 常用软件写网页html,新手用什么软件写html网页比较靠谱
  14. 计算机网络发展分几个阶段各有什么特点,计算机网络的发展可以划分为几个阶段?每个阶段都有什么特点?...
  15. 9款常用的数据可视化工具推荐
  16. c语言析构函数的作用,详解析构函数出现的必要性
  17. 【约束 约束 约束】
  18. 《行为经济学》北京大学 孟涓涓 第四章
  19. 用Python学《微积分B》(多元函数的极限)
  20. 【计算机考研408】磁盘的初始化过程

热门文章

  1. 爱普搜 | 2021年1月零售汽车销量排名
  2. excel数据库_Excel再厉害的高手,也敌不过Access数据库的新手
  3. windows防火墙设置_Windows防火墙:您应该知道的事情
  4. github的博客搭建以及标签的自动化
  5. #榜样的力量#航班管家全球大交通出行疫情追踪服务系统丨数据猿新冠战“疫”公益策划...
  6. 写毕业论文更新目录时,如何让格式不会变?
  7. CCF-CSP-201409-5 拼图
  8. Vue Router 实现路由控制实战
  9. Markdown还能这么玩?这款开源神器绝了
  10. 编译-POCO C++支持iOS平台的静态库