题目描述

小 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就好了,只是稍稍有点变化。

 #include<cstdio>
#include<iostream>
#define ll long long
#define Maxn 1000000001
#define RG register
#define il inline
using namespace std;
ll a,b,K,mod,mod2,mod5,v[][];
ll pw(ll x,ll y,ll Mod){
ll res = ;
while(y){
if(y&) res = res * x % Mod;
y>>=; x = x * x % Mod;
}
return res;
}
void init(ll k,ll mx){
ll typ = k!=;
v[typ][] = ;
for(RG ll i = ;i <= mx;i++){
if(i%k) v[typ][i] = v[typ][i - ]*i % mx;
else v[typ][i] = v[typ][i - ];
}
}
inline void exgcd(ll a,ll b,ll &x,ll &y){
if(!b) {x = ,y = ;}
else exgcd(b,a%b,y,x),y -= a/b*x;
}
ll inv(ll a,ll p){
ll x,y; exgcd(a,p,x,y);
return (x%p+p)%p;
}
il ll mul(ll n,ll p,ll pk){
if(!n) return ;
ll ret = pw(v[p!=][pk],n / pk,pk) * v[p!=][n % pk] % pk;
return ret * mul(n / p,p,pk) % pk;
}
ll C(ll n,ll m,ll p,ll pk,ll fg){
if(n<m) return ;
ll cnt = ;
for(RG ll i = n;i;i/=p) cnt += i / p;
for(RG ll i = m;i;i/=p) cnt -= i / p;
for(RG ll i = (n - m);i;i/=p) cnt -= i / p;
if(p==&&fg) cnt--;
if(cnt>=K) return ;
ll s1 = mul(n,p,pk),s2 = mul(m,p,pk),s3 = mul(n - m,p,pk);
ll ret = pw(p,cnt,pk) * s1 % pk * inv(s2,pk) % pk * inv(s3,pk) % pk;
if(p==&&fg) ret = ret * inv(,pk) % pk;
return ret * (mod / pk) % mod * inv(mod / pk,pk) % mod;
}
ll lucas(ll n,ll m,ll fg) {return (C(n,m,,mod2,fg) + C(n,m,,mod5,fg)) % mod;}
int main()
{ //freopen("bzoj4830.in","r",stdin);
//freopen("bzoj4830.out","w",stdout);
init(,); init(,);
while(cin >> a >> b >> K){
mod2 = pw(,K,Maxn); mod5 = pw(,K,Maxn); mod = pw(,K,Maxn);
ll ans = pw(,a + b - ,mod);
if(a==b) ans = (ans - lucas(a+b,a,) + mod) % mod;
else {
for(RG ll i = (a+b)/+;i<a;i++) ans = (ans + lucas(a+b,i,))%mod;
if(!((a+b)%)) ans = (ans + lucas(a+b,(a+b)/,)) % mod;
}
while(ans<mod/) mod/=,printf("");
printf("%lld\n",ans);
}
return ;
}//by tkys_Austin;

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

bzoj4830 hnoi2017 抛硬币的更多相关文章

  1. BZOJ4830 [Hnoi2017]抛硬币 【扩展Lucas】

    题目链接 BZOJ4830 题解 当\(a = b\)时,我们把他们投掷硬币的结果表示成二进制,发现,当\(A\)输给\(B\)时,将二进制反转一下\(A\)就赢了\(B\) 还要除去平局的情况,最后 ...

  2. 【BZOJ4830】[HNOI2017]抛硬币(组合计数,拓展卢卡斯定理)

    [BZOJ4830][HNOI2017]抛硬币(组合计数,拓展卢卡斯定理) 题面 BZOJ 洛谷 题解 暴力是啥? 枚举\(A\)的次数和\(B\)的次数,然后直接组合数算就好了:\(\display ...

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

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

  4. bzoj 4830: [Hnoi2017]抛硬币

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

  5. [AH/HNOI2017]抛硬币

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

  6. luogu P3726 [AH2017/HNOI2017]抛硬币

    传送门 我是真的弱,看题解都写了半天,,, 这题答案应该是\(\sum_{i=1}^{a}\binom{a}{i}\sum_{j=0}^{min(b,i-1)}\binom{b}{j}\) 上面那个式 ...

  7. 【刷题】BZOJ 4830 [Hnoi2017]抛硬币

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

  8. [HNOI2017]抛硬币

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

  9. [luogu3726 HNOI2017] 抛硬币 (拓展lucas)

    传送门 数学真的太优秀了Orz 数据真的太优秀了Orz 题目描述 小 A 和小 B 是一对好朋友,他们经常一起愉快的玩耍.最近小 B 沉迷于**师手游,天天刷本,根本无心搞学习.但是已经入坑了几个月, ...

随机推荐

  1. 团队作业4——第一次项目冲刺(Alpha版本) Day 2

    小队@JMUZJB-集美震惊部 一.Daily Scrum Meeting照片 二.Burndown Chart 燃尽图 三.项目进展 成员 工作 丘雨晨 环境配置 刘向东 数据库搭建,环境配置 江泽 ...

  2. 【iOS】OC-Quartz2D简单使用

    什么是Quartz2D Quartz 2D是一个二维绘图引擎,同时支持iOS和Mac系统 作用 ? 1 2 3 4 5 6 7 8 9 <code>Quartz 2D能完成的工作 绘制图形 ...

  3. 从PRISM开始学WPF(六)MVVM(二)Command?

    从PRISM开始学WPF(一)WPF? 从PRISM开始学WPF(二)Prism? 从PRISM开始学WPF(三)Prism-Region? 从PRISM开始学WPF(四)Prism-Module? ...

  4. [笔试题目]使用Stringbuffer无 参的构造函数创建 一个对象时,默认的初始容量是多少? 如果长度不够使用了,自动增长多少倍?

    [笔试题目] 使用Stringbuffer无 参的构造函数创建 一个对象时,默认的初始容量是多少? 如果长度不够使用了,自动增长多少倍? StringBuffer 底层是依赖了一个字符数组才能存储字符 ...

  5. redis入门(14)redis集群下的数据分区存储

    redis入门(10)redis集群下的数据分区存储

  6. 阿里云API网关(3)快速入门(调用 API)

    网关指南: https://help.aliyun.com/document_detail/29487.html?spm=5176.doc48835.6.550.23Oqbl 网关控制台: https ...

  7. OrientDB入门(1)Getting Started

    Running OrientDB the First Time First, download and extract OrientDB by selecting the appropriate pa ...

  8. linux下git常用命令

    1 安装: sudo apt-get install git 2 创建一个版本库: 新建一个文件夹,进入这个目录之后 git init 3 创建一个版本: git add 文件名或目录 #表示将当前文 ...

  9. SpringMVC(五):@RequestMapping下使用@RequestParam绑定请求参数值

    在处理方法入参使用@RequestParam可以把请求参数传递给请求方法,@RequestParam包含的属性值: --- value :参数名称 --- required :是否必须,默认为true ...

  10. js 常用数组和字符串方法

    javascript数组与字符串常用方法总结 最近在梳理js的基础,首先从数组和字符串开始. string 常用方法: 1.substring(start开始位置的索引,end结束位置索引) 截取的位 ...