传送门

我是真的弱,看题解都写了半天,,,

这题答案应该是\(\sum_{i=1}^{a}\binom{a}{i}\sum_{j=0}^{min(b,i-1)}\binom{b}{j}\)

上面那个式子无法化简qwq

把A和b的抛硬币情况连在一起,记成一个01串,那么如果某个串代表B获胜,那么这个串的反串就能代表A获胜

如果\(a=b\),那么答案还要减去平局情况,即$$\frac{2^{a+b}-\binom{a+b}{a}}{2}$$

如果\(a>b\),那么有种特殊情况是代表A获胜的某个串反串还是代表A获胜,这种情况假设B硬币朝上个数为\(i\),A的朝上个数比B多\(i\),那么有\(b-i<a-i-j\),情况数量有$$\sum_{i=0}{b}\sum_{j=1}{a-b-1}\binom{a}{i+j}\binom{b}{i}$$个,也就是$$\sum_{i=0}{b}\sum_{j=1}{a-b-1}\binom{a}{i+j}\binom{b}{b-i}$$然后有个什么范德蒙德卷积,就是\(\sum_{i+j=k}\binom{a}{i}\binom{b}{j}=\binom{a+b}{k}\),所以上式化简为$$\sum_{i=1}^{a-b-1}\binom{a+b}{b+i}$$

答案即$$\frac{2{a+b}+\sum_{i=1}{a-b-1}\binom{a+b}{b+i}}{2}$$

然后因为模数不为质数,所以组合数要用\(exlucas\)求

注意在实现的时候要优化时间复杂度,例如预处理模2和模5的阶乘等

#include<bits/stdc++.h>
#define LL long long
#define il inline
#define re register
#define db double using namespace std;
il LL rd()
{
LL x=0,w=1;char ch=0;
while(ch<'0'||ch>'9') {if(ch=='-') w=-1;ch=getchar();}
while(ch>='0'&&ch<='9') {x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
return x*w;
}
LL a,b,k,K,k2,k5;
LL fc[2][2000000];
int pm[30][2],tt;
il LL fpow(LL a,LL b,LL mod)
{
LL an=1;
while(b){if(b&1) an=an*a%mod;a=a*a%mod,b>>=1;}
return an;
}
il void exgcd(LL a,LL b,LL &x,LL &y)
{
if(!b) {x=1,y=0;return;}
exgcd(b,a%b,y,x);
y-=a/b*x;
}
il LL ginv(LL a,LL b)
{
LL x,y;
exgcd(a,b,x,y);
return (x%b+b)%b;
}
il LL fac(LL n,LL p1,LL pk)
{
if(n<=1) return 1;
LL an=fpow(fc[p1&1][pk],n/pk,pk)*fc[p1&1][n%pk]%pk;
return an*fac(n/p1,p1,pk)%pk;
}
il LL C(LL n,LL m,LL p1,LL pk,bool d2)
{
LL kk=0;
for(LL i=n;i;i/=p1) kk+=i/p1;
for(LL i=m;i;i/=p1) kk-=i/p1;
for(LL i=n-m;i;i/=p1) kk-=i/p1;
if(kk-1>=k) return 0; //kk-1>=k,所以a*p^kk=0(mod p^k)
if(d2)
{
if(p1&1) kk=fpow(p1,kk,pk)*ginv(2,pk)%pk;
else kk=fpow(p1,kk-1,pk);
}
else kk=fpow(p1,kk,pk);
return fac(n,p1,pk)*ginv(fac(m,p1,pk),pk)%pk*ginv(fac(n-m,p1,pk),pk)%pk*kk%pk;
}
il LL exlcs(LL n,LL m,bool d2)
{
return (C(n,m,2,k2,d2)*k5%K*ginv(k5,k2)%K+C(n,m,5,k5,d2)*k2%K*ginv(k2,k5)%K)%K;
}
il void init(int a,int b)
{
int px=a&1;
fc[px][0]=1;
for(int i=1;i<=b;++i)
{
fc[px][i]=fc[px][i-1];
if(i%a) fc[px][i]=fc[px][i]*i%b;
}
} //预处理fac函数中的计算部分
il void print(int x,int kk)
{
kk/=10;
while(kk) putchar(x/kk%10+'0'),kk/=10;
putchar('\n');
} int main()
{
init(2,512),init(5,1953125);
while(scanf("%lld%lld%lld",&a,&b,&k)!=-1)
{
K=k2=k5=1;
int kb=k;while(kb--) K*=10,k2*=2,k5*=5;
if(a==b) print((fpow(2,a+b-1,K)-exlcs(a+b,a,1)+K)%K,K);
else
{
LL an=fpow(2,a+b-1,K);
for(LL i=b+1;i<=(a+b)/2;++i)
an=(an+exlcs(a+b,i,0)%K)%K; //根据C(a,b)=C(a,a-b)省去一半计算
if(!((a+b)&1)) an=(an-exlcs(a+b,(a+b)/2,1)+K)%K;
print(an,K);
}
}
return 0;
}

luogu P3726 [AH2017/HNOI2017]抛硬币的更多相关文章

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

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

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

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

  3. 题解 洛谷 P3726 【[AH2017/HNOI2017]抛硬币】

    可以分别枚举两人正面朝上的次数来统计答案,所求即为 \[\sum_{i=0}^{a}\sum_{j=0}^{b} \binom{a}{i} \binom{b}{j} [i>j] \] 将\(i\ ...

  4. [AH2017/HNOI2017]抛硬币

    传送门 这个题的暴力比较好想--然后用一些组合的知识就可以变成正解了. 首先我们考虑a=b的情况.我们把扔出来的硬币看成是一个01序列,那么对于一个b获胜的序列,他在每一位都按位异或1之后必然是一个a ...

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

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

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

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

  7. [Luogu P3723] [AH2017/HNOI2017]礼物 (FFT 卷积)

    题面 传送门:洛咕 Solution 调得我头大,我好菜啊 好吧,我们来颓柿子吧: 我们可以只旋转其中一个手环.对于亮度的问题,因为可以在两个串上增加亮度,我们也可以看做是可以为负数的. 所以说,我们 ...

  8. bzoj 4830: [Hnoi2017]抛硬币

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

  9. [AH/HNOI2017]抛硬币

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

随机推荐

  1. 【LOJ#6277】数列分块1

    题目大意:维护一个长度为 N 的序列,支持区间修改.单点查询. 代码如下 #include <bits/stdc++.h> using namespace std; const int m ...

  2. IO 流读取文件时候出现乱码 文件编码格式问题 怎么转换解决方法

    在使用下面这个写法时候UTF-8文件编码 在读取时候出现乱码问题. File myFile=new File("文件路径"); BufferedReader in = new Bu ...

  3. 第十三节,使用带有全局平均池化层的CNN对CIFAR10数据集分类

    这里使用的数据集仍然是CIFAR-10,由于之前写过一篇使用AlexNet对CIFAR数据集进行分类的文章,已经详细介绍了这个数据集,当时我们是直接把这些图片的数据文件下载下来,然后使用pickle进 ...

  4. windows下ngnix+php配置

    1.需要工具: 下载ngnix  网址:http://nginx.org/ 下载:RunHiddenConsole 第二步 将下载文件解压后,将RunHiddenConsole拷贝到ngnix目录与p ...

  5. (Prim算法)codeVs 1078 最小生成树

    题目描述 Description 农民约翰被选为他们镇的镇长!他其中一个竞选承诺就是在镇上建立起互联网,并连接到所有的农场.当然,他需要你的帮助. 约翰已经给他的农场安排了一条高速的网络线路,他想把这 ...

  6. redis命令参考和redis文档中文翻译版

    找到了一份redis的中文翻译文档,觉得适合学习和查阅.这份文档翻译的真的很良心啊,他是<Redis 设计与实现>一书的作者黄健宏翻译的. 地址:http://redisdoc.com/i ...

  7. MySQL语句_积累

    1.GROUP_CONCAT 直接返回拼接好的多个结果,可以供IN()函数使用 语句 结果 +-----------------------------------------+ | GROUP_CO ...

  8. java 中数据的强制转换 和计算的补码运算

    原码 反码 补码的定义与运算 1原码: 原码是将十进制或者其他进制的数转换为二进制表示(且要根据数据的类型转换) 如:130 (默认是Int类型,则是4个字节) 原码是:00000000 000000 ...

  9. Linux安装npm并打包前端代码

    查看node版本$ node -v查看npm版本$ npm -v如果没有安装node及npm,需要先安装node及npm#yum install node# yum install npm安装cnpm ...

  10. mysql 遍历所有的库并根据表和sql语句备份

    建库.用户语句 create database test_hb; create user ' test_hb'@'%' identified by '123456'; grant all privil ...