题目描述

小 A 和小 B 是一对好朋友,他们经常一起愉快的玩耍。最近小 B 沉迷于**师手游,天天刷本,根本无心搞学习。但是已经入坑了几个月,却一次都没有抽到 SSR,让他非常怀疑人生。勤勉的小 A 为了劝说小 B 早日脱坑,认真学习,决定以抛硬币的形式让小 B 明白他是一个彻彻底底的非洲人,从而对这个游戏绝望。两个人同时抛 b 次硬币,如果小 A 的正面朝上的次数大于小 B 正面朝上的次数,则小 A 获胜。

但事实上,小 A 也曾经沉迷过拉拉游戏,而且他一次 UR 也没有抽到过,所以他对于自己的运气也没有太大把握。所以他决定在小 B 没注意的时候作弊,悄悄地多抛几次硬币,当然,为了不让小 B 怀疑,他不会抛太多次。现在小 A 想问你,在多少种可能的情况下,他能够胜过小 B 呢?由于答案可能太大,所以你只需要输出答案在十进制表示下的最后 k 位即可。

输入输出格式

输入格式:

有多组数据,对于每组数据输入三个数a,b,k,分别代表小A抛硬币的次数,小B抛硬币的次数,以及最终答案保留多少位整数。

输出格式:

对于每组数据,输出一个数,表示最终答案的最后 k 位为多少,若不足 k 位以 0 补全。

题意:

小A可以抛a次硬币,小B可以抛b次硬币(a>=b)问小A抛出正面的次数比小B多的情况种数,输出对10的k次方取余(k<=9);

题解:

①这是一个利用对应关系进行构造的组合问题:

如果每一种小A赢情况对应(把a,b次抛出的结果正面变成反面)一种小B赢的情况,那么总可能数/2就是答案,但是事实上不是,在可能会有小A无论在两种情况下都是比小B多,或者小A在两种情况下都小于等于小B的次数,为此,就只有分a=b和a>b讨论。

②a=b

A和B掷出的正面相同,小A两种情况都赢不了

$F = \sum_{i=0}^{a}C_{a}^{i}C_{a}^{i}=\sum_{i=0}^{a}C_{a}^{i}C_{a}^{a-i} = C_{2a}^{a}$

(a选i个再在另外a个选a-i个和在2a个里选a个一一对应)

$ans = \frac{2^{2a}-F}{2} = \frac{2^{2a}-C_{2a}^{a}}{2}$

③a>b

A和B掷出的正面满足A>B且a-A>b-B时小A两种情况都可以赢小B

$G = \sum_{i=0}^{b}\sum_{j=1}^{a-b-1}C_{b}^{i}C_{a}^{i+j} = \sum_{i=0}^{b}\sum_{j=1}^{a-b-1}C_{b}^{b-i}C_{a}^{i+j} = \sum_{j=1}^{a-b-1}C_{a+b}^{j+b}$ 

(b个里选b-i个再在a个里选i+j个一一对应在a+b个里选b+j个)

$ans = \frac{2^{2a}+G}{2} = \frac{2^{2a}+\sum_{j=1}^{a-b-1}C_{a+b}^{j+b}}{2}$

剩下的组合数取模用扩展lucas就好了,只是稍稍有点变化。

 1 #include<cstdio>
 2 #include<iostream>
 3 #define ll long long
 4 #define Maxn 1000000001
 5 #define RG register
 6 #define il inline
 7 using namespace std;
 8 ll a,b,K,mod,mod2,mod5,v[2][2500005];
 9 ll pw(ll x,ll y,ll Mod){
10     ll res = 1;
11     while(y){
12         if(y&1) res = res * x % Mod;
13         y>>=1; x = x * x % Mod;
14     }
15     return res;
16 }
17 void init(ll k,ll mx){
18     ll typ = k!=2;
19     v[typ][0] = 1;
20     for(RG ll i = 1;i <= mx;i++){
21         if(i%k) v[typ][i] = v[typ][i - 1]*i % mx;
22         else v[typ][i] = v[typ][i - 1];
23     }
24 }
25 inline void exgcd(ll a,ll b,ll &x,ll &y){
26     if(!b) {x = 1,y = 0;}
27     else exgcd(b,a%b,y,x),y -= a/b*x;
28 }
29 ll inv(ll a,ll p){
30     ll x,y; exgcd(a,p,x,y);
31     return (x%p+p)%p;
32 }
33 il ll mul(ll n,ll p,ll pk){
34     if(!n) return 1;
35     ll ret = pw(v[p!=2][pk],n / pk,pk) * v[p!=2][n % pk] % pk;
36     return ret * mul(n / p,p,pk) % pk;
37 }
38 ll C(ll n,ll m,ll p,ll pk,ll fg){
39     if(n<m) return 0;
40     ll cnt = 0;
41     for(RG ll i = n;i;i/=p) cnt += i / p;
42     for(RG ll i = m;i;i/=p) cnt -= i / p;
43     for(RG ll i = (n - m);i;i/=p) cnt -= i / p;
44     if(p==2&&fg) cnt--;
45     if(cnt>=K) return 0;
46     ll s1 = mul(n,p,pk),s2 = mul(m,p,pk),s3 = mul(n - m,p,pk);
47     ll ret = pw(p,cnt,pk) * s1 % pk * inv(s2,pk) % pk * inv(s3,pk) % pk;
48     if(p==5&&fg) ret = ret * inv(2,pk) % pk;
49     return ret * (mod / pk) % mod * inv(mod / pk,pk) % mod;
50 }
51 ll lucas(ll n,ll m,ll fg) {return (C(n,m,2,mod2,fg) + C(n,m,5,mod5,fg)) % mod;}
52 int main()
53 {    //freopen("bzoj4830.in","r",stdin);
54     //freopen("bzoj4830.out","w",stdout);
55     init(2,512); init(5,1953125);
56     while(cin >> a >> b >> K){
57         mod2 = pw(2,K,Maxn); mod5 = pw(5,K,Maxn); mod = pw(10,K,Maxn);
58         ll ans = pw(2,a + b - 1,mod);
59         if(a==b) ans = (ans - lucas(a+b,a,1) + mod) % mod;
60         else {
61             for(RG ll i = (a+b)/2+1;i<a;i++) ans = (ans + lucas(a+b,i,0))%mod;
62             if(!((a+b)%2)) ans = (ans + lucas(a+b,(a+b)/2,1)) % mod;
63         }
64         while(ans<mod/10) mod/=10,printf("0");
65         printf("%lld\n",ans);
66     }
67     return 0;
68 }//by tkys_Austin;

(快省选了,关于扩lucas,扩gcd,扩CRT的叙述后面有时间可能会补上)

转载于:https://www.cnblogs.com/Paul-Guderian/p/8647074.html

bzoj4830 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. [AH2017/HNOI2017]抛硬币

    一.题目 点此看题 二.解法 前置芝士:范德蒙德卷积: 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)= ...

  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. 有道概率题:一个有趣的抛硬币问题

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

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

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

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

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

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

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

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

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

  9. 用贝叶斯来看看抛硬币的概率

    前面介绍了贝叶斯学派的思想和先验分布.后验分布的相关知识,古典频率学派认为抛硬币的概率是常数,本文从贝叶斯学派的角度看待抛硬币的概率问题.本文详细介绍了  分布,重述贝叶斯思想,对于抛硬币的概率问题作 ...

最新文章

  1. 程序员大厂不一定要进,算法必须要学!收藏89篇精选算法文章
  2. 50 多万个项目陷入混乱!只因代码库许可协议不兼容
  3. Fedora 18 正式发布
  4. hook 与aspectj_将AspectJ与NetBeans平台开发集成
  5. 某Q娱乐网emlog程序整站源码
  6. php点击按钮弹窗提示,WEB表单,给出弹出框提示,点击按钮报错
  7. php定时执行代码漏洞_在CTF比赛中发现的PHP远程代码执行0day漏洞
  8. 差分输出和单端输出的区别(转载)
  9. 虚拟机中CentOS系统安装流程
  10. thinkpadt410接口介绍_ThinkPadT410全程拆解
  11. 有哪些不错的数学、物理类的「闲书」?
  12. 面向机器学习的自然语言标注2.4 语料库的规模
  13. 家庭电信网弄外网唤醒并远程内网电脑
  14. 你真的了解开源镜像站吗?
  15. html里子目录,技术宅文之还电脑屏幕原来的百富美姿态_html/css_WEB-ITnose
  16. 用cookie登录KinhDown教程
  17. 【硬件】常见芯片封装技术
  18. Arduino文档阅读笔记-4 WHEEL ROBOT CAR BASIC EXAMPLE
  19. 【教程】farmskins怎么玩
  20. Java选择与循环语句

热门文章

  1. java 三级考试_java web 学习 --第三天(Java三级考试)
  2. 斯坦德机器人收购_斯坦德机器人合伙人兼CMO王茂林:人是公司发展根本,多数企业都死于合伙人...
  3. 简述php中文件上传过程,简单php文件上传详细说明
  4. java accept charset_springmvc中post请求中文乱码问题
  5. c语言50到100套,c语言51-100套试题答案及详解.pdf
  6. 虚拟机centos7忘记密码怎么办_电脑忘记密码怎么办
  7. Apriltag可用图片:TAG16H5
  8. 2021-06-082021年春季学期-信号与系统-第十五次作业-第四小题参考答案
  9. 全国大学生智能汽车竞赛-讯飞赛道规则解读
  10. 电路纹身-疼痛的快乐