题目链接

BZOJ4830

题解

当\(a = b\)时,我们把他们投掷硬币的结果表示成二进制,发现,当\(A\)输给\(B\)时,将二进制反转一下\(A\)就赢了\(B\)

还要除去平局的情况,最后答案就是

\[\frac{2^{a + b} - {a + b \choose a}}{2}
\]

当\(a \neq b\)时,有些状态可能翻转后还是\(A\)赢\(B\),需要加上这部分

\[\begin{aligned}
\sum\limits_{i = 0}^{b} \sum\limits_{j = 1}^{a - b - 1}{b \choose i} {a \choose i + j}
&= \sum\limits_{j = 1}^{a - b - 1} \sum\limits_{i = 0}^{b} {b \choose b - i} {a \choose i + j} \\
&= \sum\limits_{j = 1}^{a - b - 1} {a + b \choose b + j} \\
&= \sum\limits_{j = b + 1}^{a - 1} {a + b \choose j} \\
\end{aligned}
\]

答案是

\[\frac{2^{a + b} + \sum\limits_{j = b + 1}^{a - 1} {a + b \choose j} }{2}
\]

除\(2\)的处理,因为组合数是对称的,所以只算一半

如果中间单独剩一个,一定可以被\(2\)整除,处理因子时减去一个即可

由于要模\(10^{K}\),组合数的计算用扩展\(Lucas\)

此题非常卡常,要使用扩展\(Lucas\)的一些优化

1.预处理阶乘

2.当\(p\)的幂次大于\(k\)时直接返回\(0\)

3.没了

#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<iomanip>
#include<cstdio>
#include<vector>
#include<queue>
#include<ctime>
#include<cmath>
#include<map>
#define LL long long int
#define REP(i,n) for (LL i = 1; i <= (n); i++)
#define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
#define cls(s,v) memset(s,v,sizeof(s))
#define mp(a,b) make_pair<int,int>(a,b)
#define cp pair<int,int>
using namespace std;
const int maxn = 2000005,maxm = 100005,INF = 0x3f3f3f3f;
int K,pr[2],pk[2],P,fac[2][maxn],now,ans;
LL A,B;
void init(){
pr[0] = 2; pr[1] = 5; pk[0] = pk[1] = P = fac[0][0] = fac[1][0] = 1;
REP(i,K) pk[0] *= 2,pk[1] *= 5,P *= 10;
for (LL i = 1; i < pk[0]; i++)
if (i % 2) fac[0][i] = 1ll * fac[0][i - 1] * i % pk[0];
else fac[0][i] = fac[0][i - 1];
for (LL i = 1; i < pk[1]; i++)
if (i % 5) fac[1][i] = 1ll * fac[1][i - 1] * i % pk[1];
else fac[1][i] = fac[1][i - 1];
}
inline int qpow(int a,LL b,int p){
int re = 1;
for (; b; b >>= 1,a = 1ll * a * a % p)
if (b & 1) re = 1ll * re * a % p;
return re;
}
inline void exgcd(int a,int b,int&d ,int& x,int& y){
if (!b){d = a; x = 1; y = 0;}
else exgcd(b,a % b,d,y,x),y -= (a / b) * x;
}
inline int inv(int n,int p){
int d,x,y; exgcd(n,p,d,x,y);
return (x % p + p) % p;
}
int Fac(LL n,int pk,int p){
if (!n) return 1;
return 1ll * qpow(fac[now][pk - 1],n / pk,pk) * fac[now][n % pk] % pk * Fac(n / p,pk,p) % pk;
}
int C(LL n,LL m,int pk,int p,bool f){
LL k = 0;
for (LL i = n; i; i /= p) k += i / p;
for (LL i = m; i; i /= p) k -= i / p;
for (LL i = n - m; i; i /= p) k -= i / p;
if (p == 2 && f) k--;
if (k >= 9) return 0;
now = (p == 5);
LL a = Fac(n,pk,p),b = Fac(m,pk,p),c = Fac(n - m,pk,p),ans;
ans = a * inv(b,pk) % pk * inv(c,pk) % pk;
if (p == 5 && f) ans = 1ll * ans * inv(2,pk) % P;
ans = ans * qpow(p,k,pk) % pk;
return ans * (P / pk) % P * inv(P / pk,pk) % P;
}
int exlucas(LL n,LL m,bool f){
if (m > n) return 0;
int re = 0;
re = (re + C(n,m,pk[0],pr[0],f)) % P;
re = (re + C(n,m,pk[1],pr[1],f)) % P;
return re;
}
int main(){
//double t = clock();
K = 9; init();
while (~scanf("%lld%lld%d",&A,&B,&K)){
ans = qpow(2,A + B - 1,P);
if (A == B) ans = ((ans - exlucas(A + B,A,1)) % P + P) % P;
else {
for (LL i = ((A + B) >> 1) + 1; i < A; i++){
ans = (ans + exlucas(A + B,i,0)) % P;
}
if ((A + B) % 2 == 0) ans = (ans + exlucas(A + B,(A + B) >> 1,1)) % P;
}
int md = qpow(10,K,INF); ans %= md;
while (ans < md / 10) putchar('0'),md /= 10;
printf("%d\n",ans);
}
//cerr << (clock() - t) / CLOCKS_PER_SEC << endl;
return 0;
}

BZOJ4830 [Hnoi2017]抛硬币 【扩展Lucas】的更多相关文章

  1. bzoj4830 hnoi2017 抛硬币

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

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

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

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

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

  4. [AH2017/HNOI2017]抛硬币(扩展lucas)

    推式子+exlucas. 题意: 小 A 和小 B 是一对好朋友,两个人同时抛 b 次硬币,如果小 A 的正面朝上的次数大于小 B 正面朝上的次数,则小 A 获胜. 小 A 决定在小 B 没注意的时候 ...

  5. 洛谷P3726 [AH2017/HNOI2017]抛硬币(组合数+扩展Lucas)

    题面 传送门 题解 果然--扩展\(Lucas\)学了跟没学一样-- 我们先考虑\(a=b\)的情况,这种情况下每一个\(A\)胜的方案中\(A\)和\(B\)的所有位上一起取反一定是一个\(A\)败 ...

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

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

  7. bzoj 4830: [Hnoi2017]抛硬币

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

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

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

  9. [AH/HNOI2017]抛硬币

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

随机推荐

  1. Scala--操作符

    一.标识符 二.中置操作符 中置表达式,操作符位于两个参数之间 1 to 10 1.to(10) 1 -> 10 1.->(10) 三.一元操作符 a.标识符() 1 toString 1 ...

  2. Android应用安全之第三方SDK安全

    第三方sdk的包括广告.支付.统计.社交.推送,地图等类别,是广告商.支付公司.社交.推送平台,地图服务商等第三方服务公司为了便于应用开发人员使用其提供的服务而开发的工具包,封装了一些复杂的逻辑实现以 ...

  3. python基础学习1-变量定义赋值,屏幕输入输出

    一.变量定义赋值 输入输出屏幕显示 : name = input("input is your name") age =int( input("input is your ...

  4. python 回溯法 子集树模板 系列 —— 10、m着色问题

    问题 图的m-着色判定问题 给定无向连通图G和m种不同的颜色.用这些颜色为图G的各顶点着色,每个顶点着一种颜色,是否有一种着色法使G中任意相邻的2个顶点着不同颜色? 图的m-着色优化问题 若一个图最少 ...

  5. [图片生成]使用VAEs生成新图片

    变分自动编码器生成图片 从隐图像空间进行采样以创建全新的图像或编辑现有图像是目前创作AI最受欢迎和最成功的应用方式. 图像隐空间取样 图像生成的关键思想是开发表示的低维潜在空间(自然是矢量空间),其中 ...

  6. Hadoop日记Day16---命令行运行MapReduce程序

    一.代码编写 1.1 单词统计 回顾我们以前单词统计的例子,如代码1.1所示. package counter; import java.net.URI; import org.apache.hado ...

  7. JavaScript 变量提升

    变量提升(Hoisting):在ES6之前,函数声明和变量声明总是被JavaScript解释器隐式地提升(hoist)到包含他们的作用域的最顶端. 注意: 1. JavaScript 仅提升声明,而不 ...

  8. MongoDB的账户与权限管理及在Python与Java中的登录

    本文主要介绍了MongoDB的账户新建,权限管理(简单的),以及在Python,Java和默认客户端中的登陆. 默认的MongoDB是没有账户权限管理的,也就是说,不需要密码即可登陆,即可拥有读写的权 ...

  9. Js_判断浏览器

    var isIE=!!window.ActiveXObject;var isIE6=isIE&&!window.XMLHttpRequest;var isIE8=isIE&&a ...

  10. 《Pro SQL Server Internals, 2nd edition》的CHAPTER 2 Tables and Indexes中的Clustered Indexes一节(翻译)

    <Pro SQL Server Internals> 作者: Dmitri Korotkevitch 出版社: Apress出版年: 2016-12-29页数: 804定价: USD 59 ...