洛谷P3726 [AH2017/HNOI2017]抛硬币(组合数+扩展Lucas)
题面
题解
果然……扩展\(Lucas\)学了跟没学一样……
我们先考虑\(a=b\)的情况,这种情况下每一个\(A\)胜的方案中\(A\)和\(B\)的所有位上一起取反一定是一个\(A\)败的方案,而平局的方案取反之后仍然是一个平局的方案。那么我们可以用总的方案数\(2^{a+b}\)减去平局的次数除以\(2\)就行了。平局的次数我们可以考虑枚举两边扔了多少次正面,那么答案就是
\]
可以这么证明,\({n\choose i}={n\choose n-i}\),所以\({n\choose i}^2={n\choose i}\times {n\choose n-i}\),可以看做是左边\(n\)个里取\(i\)个的方案,右边\(n\)个里取\(n-i\)个的方案。然后我们枚举\(i\),最后就等价于从\(2n\)个物品里选择\(n\)个物品的方案
接下来是\(a>b\)的情况,首先一种\(A\)败或平局的方案取反之后一定是\(A\)胜。然后\(A\)胜取反之后可能还是\(A\)胜。所以我们需要用总方案数加上\(A\)取反之后仍然获胜的方案数再除以\(2\)
设\(W_A\)表示\(A\)获胜的次数,\(W_B\)同理,那么我们就是要满足\(W_A>W_B\)且\(a-W_A>b-W_B\),化简之后可得\(a-b>W_A-W_B>0\)
那么我们枚举\(W_B\)和\(W_A-W_B\),有
ans
&=\sum_{i=0}^b\sum_{j=1}^{a-b-1}{b\choose i}{a\choose i+j}\\
&=\sum_{i=0}^b\sum_{j=1}^{a-b-1}{b\choose b-i}{a\choose i+j}\\
&=\sum_{j=1}^{a-b-1}\sum_{i=0}^b{b\choose b-i}{a\choose i+j}\\
&=\sum_{j=1}^{a-b-1}\sum_{i+k=b+j}{b\choose i}{a\choose k}\\
&=\sum_{j=1}^{a-b-1}{a+b\choose b+j}\\
\end{aligned}
\]
然后就\(ok\)了,剩下的用扩展\(Lucas\)计算就行了
//minamoto
#include<bits/stdc++.h>
#define R register
#define ll long long
#define fp(i,a,b) for(R int i=a,I=b+1;i<I;++i)
#define fd(i,a,b) for(R int i=a,I=b-1;i>I;--i)
#define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
using namespace std;
const int N=2e6+5,inf=2147483647;
int fac[2][N],P,k,d1,d2,res;ll a,b;
inline int mul(R int x,R int y,R int p){return 1ll*x*y-1ll*x*y/p*p;}
int ksm(R int x,R ll y,R int p){
R int res=1;
for(;y;y>>=1,x=1ll*x*x%p)if(y&1)res=1ll*res*x%p;
return res;
}
void exgcd(int a,int b,int &x,int &y){
if(!b)return x=1,y=0,void();
exgcd(b,a%b,y,x),y-=a/b*x;
}
inline int Inv(int n,int p){
if(!n)return 0;
int x,y;exgcd(n,p,x,y);
x=(x%p+p)%p;return x?x:x+p;
}
int Fac(ll n,int pi,int pk){
if(!n)return 1;
int res=ksm(fac[pi!=2][pk],n/pk,pk);
return 1ll*res*fac[pi!=2][n%pk]%pk*Fac(n/pi,pi,pk)%pk;
}
int C(ll n,ll m,int pi,int pk){
if(n<m)return 0;
int r=0;
for(R ll i=n;i;i/=pi)r+=i/pi;
for(R ll i=m;i;i/=pi)r-=i/pi;
for(R ll i=n-m;i;i/=pi)r-=i/pi;
if(r>=k)return 0;
int a=Fac(n,pi,pk),b=Fac(m,pi,pk),c=Fac(n-m,pi,pk),res;
res=1ll*a*Inv(b,pk)%pk*Inv(c,pk)%pk*ksm(pi,r,pk)%pk;
return 1ll*res*(P/pk)%P*Inv(P/pk,pk)%P;
}
int exLucas(ll n,ll m){
if(n<m)return 0;
int res=0;
(res+=C(n,m,2,d1))%=P;
(res+=C(n,m,5,d2))%=P;
return res;
}
void init(){
fac[0][0]=fac[1][0]=1;
fp(i,1,512)fac[0][i]=(i&1)?mul(fac[0][i-1],i,512):fac[0][i-1];
fp(i,1,1953125)fac[1][i]=(i%5)?mul(fac[1][i-1],i,1953125):fac[1][i-1];
}
int main(){
// freopen("testdata.in","r",stdin);
init();
while(~scanf("%lld%lld%d",&a,&b,&k)){
P=ksm(10,k,inf),d1=ksm(2,k,inf),d2=ksm(5,k,inf);
res=ksm(2,a+b-1,P);
if(a==b)(res+=P-exLucas((a<<1)-1,a))%=P;
else{
fp(i,1,((a-b-1)>>1))(res+=exLucas(a+b,b+i))%=P;
if(!((a+b)&1))(res+=exLucas(a+b-1,(a+b)>>1))%=P;
}
while(res<P/10)putchar('0'),P/=10;
printf("%d\n",res);
}
return 0;
}
洛谷P3726 [AH2017/HNOI2017]抛硬币(组合数+扩展Lucas)的更多相关文章
- [AH2017/HNOI2017]抛硬币(扩展lucas)
推式子+exlucas. 题意: 小 A 和小 B 是一对好朋友,两个人同时抛 b 次硬币,如果小 A 的正面朝上的次数大于小 B 正面朝上的次数,则小 A 获胜. 小 A 决定在小 B 没注意的时候 ...
- luogu P3726 [AH2017/HNOI2017]抛硬币
传送门 我是真的弱,看题解都写了半天,,, 这题答案应该是\(\sum_{i=1}^{a}\binom{a}{i}\sum_{j=0}^{min(b,i-1)}\binom{b}{j}\) 上面那个式 ...
- BZOJ4830 [Hnoi2017]抛硬币 【扩展Lucas】
题目链接 BZOJ4830 题解 当\(a = b\)时,我们把他们投掷硬币的结果表示成二进制,发现,当\(A\)输给\(B\)时,将二进制反转一下\(A\)就赢了\(B\) 还要除去平局的情况,最后 ...
- 洛谷 P3723 [AH2017/HNOI2017]礼物 解题报告
P3723 [AH2017/HNOI2017]礼物 题目描述 我的室友最近喜欢上了一个可爱的小女生.马上就要到她的生日了,他决定买一对情侣手环,一个留给自己,一个送给她.每个手环上各有 \(n\) 个 ...
- 洛谷 P3721 - [AH2017/HNOI2017]单旋(LCT)
洛谷题面传送门 终于调出来这道题了,写篇题解( 首先碰到这样的题我们肯定要考虑每种操作会对树的形态产生怎样的影响: 插入操作:对于 BST 有一个性质是,当你插入一个节点时,其在 BST 上的父亲肯定 ...
- [luogu3726 HNOI2017] 抛硬币 (拓展lucas)
传送门 数学真的太优秀了Orz 数据真的太优秀了Orz 题目描述 小 A 和小 B 是一对好朋友,他们经常一起愉快的玩耍.最近小 B 沉迷于**师手游,天天刷本,根本无心搞学习.但是已经入坑了几个月, ...
- 题解 洛谷 P3726 【[AH2017/HNOI2017]抛硬币】
可以分别枚举两人正面朝上的次数来统计答案,所求即为 \[\sum_{i=0}^{a}\sum_{j=0}^{b} \binom{a}{i} \binom{b}{j} [i>j] \] 将\(i\ ...
- [AH2017/HNOI2017]抛硬币
传送门 这个题的暴力比较好想--然后用一些组合的知识就可以变成正解了. 首先我们考虑a=b的情况.我们把扔出来的硬币看成是一个01序列,那么对于一个b获胜的序列,他在每一位都按位异或1之后必然是一个a ...
- 洛谷P3722 [AH2017/HNOI2017]影魔(线段树)
题意 题目链接 Sol 题解好神仙啊qwq. 一般看到这种考虑最大值的贡献的题目不难想到单调数据结构 对于本题而言,我们可以预处理出每个位置左边第一个比他大的位置\(l_i\)以及右边第一个比他大的位 ...
随机推荐
- 【转】 Pro Android学习笔记(八五):了解Package(4):lib项目
目录(?)[-] 什么是lib项目 小例子 Lib的实现 文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件.转载须注明出处:http://blog.csdn.net/flowing ...
- MongoDB优化之一:常见优化方法
常用性能优化方案 创建索引 限定返回结果数 只查询使用到的字段 采用capped collection 采用Server Side Code Execution 使用Hint,强制使用索引 Hint ...
- MySQL mysqldump 备份脚本(按照db.sql)
mysqldump逻辑备份,按照db.sql文件区分,并压缩 #! /bin/bash #35 02 * * * mysql /data/mysqldata/scripts/mysqldump_per ...
- [置顶]
linux getline()函数
getline()函数是什么?百度百科这样解释: getline不是C库函数,而是C++库函数.它会生成一个包含一串从输入流读入的字符的字符串,直到以下情况发生会导致生成的此字符串结束.1) ...
- 2016全国大学生信息安全竞赛(Misc)
你好,i春秋: 关注i春秋公众微信号,然后发送CTF,机器人会问星期几,按实回答,然后发送你好,机器人会回复你好,然后随便发几句,机器人会问是否愿意陪他聊天,回复不愿意,机器人就会发flag kill ...
- DAY5-模块与包
一.模块的介绍 1.什么是模块 #常见的场景:一个模块就是一个包含了一组功能的python文件,比如spam.py,模块名为spam,可以通过import spam使用. #在python中,模块的使 ...
- C run-time函数总览
Argument Access(参数访问):变长参数列表.这个模块提供了三个宏:va_arg.va_end和va_start,用来实现变长参数列表的访问. Buffer Manipulation(内存 ...
- loader的简单使用过程分析
首先,fragment或者activity必须实现callback接口 必须实现的三个方法为 public Loader<Cursor> onCreateLoader(int id, Bu ...
- 生产者与消费者-N:N-基于list
多个生产者/多个消费者: /** * 生产者 */ public class P { private MyStack stack; public P(MyStack stack) { this.sta ...
- nginx显示目录下面的文件
location / { root /data/source; index index.html index.htm; autoindex on; #autoindex指令,显示文件目录下面的 ...