[luogu3334]抛硬币
(数据范围的公式渲染有一些问题,大概是$a\le b\le 100$)
同洛谷4548,推导过程省略,直接给出答案——
令$p_{H}=\frac{b}{a}$,$p_{T}=\frac{b}{b-a}$,则$pre_{i}=\prod_{j=0}^{i-1}P_{s_{j}}$($s$下标从为$[0,n)$)
令$S=\{i|s[0,i)=s[n-i,n)\}$,则答案为$\sum_{i\in S}pre_{i}$(本来是一个后缀除以整个串)
然后这道题的坑点在于要用分数表示,之后就需要高精度
通分即先将分母都改为$pre_{n}$的分母,之后分子计算需要高精乘和除单精,可以做到$o(L^{2})$
高精度gcd通过除以2以及相减可以做到$o(L^{2})$(其中$L=2\cdot 10^{3}+3$),要写成非递归形式,否则会MLE
高精度除法二分+暴力高精度乘法可以做到$o(L^{3})$(由于fft自带的常数,$o(L^{2}\log_{2}L)$甚至会TLE)
常数较大,大概可以压$10^{7}$(防止乘100后爆int)可以过
(事实上数据极水,不约分可以得到90分)

1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N 1005
4 #define L (N<<1)
5 #define ll long long
6 #define base 10000000
7 struct ji{
8 int l,a[L];
9 }zero,one,ans_zi,ans_mu,pre[N];
10 int n,pa,pb,nex[N],rev[L<<1];
11 char s[N];
12 int cmp(ji x,ji y){//x<y则返回-1,x=y返回0,x>y返回1
13 if (x.l!=y.l)return 1-(x.l<y.l)*2;
14 for(int i=x.l;i;i--)
15 if (x.a[i]!=y.a[i])return 1-(x.a[i]<y.a[i])*2;
16 return 0;
17 }
18 ji add(ji x,ji y){
19 x.l=max(x.l,y.l);
20 for(int i=1;i<=x.l;i++){
21 x.a[i]+=y.a[i];
22 if (x.a[i]>=base){
23 x.a[i]-=base;
24 x.a[i+1]++;
25 }
26 }
27 if (x.a[x.l+1])x.l++;
28 return x;
29 }
30 ji dec(ji x,ji y){
31 for(int i=1;i<=y.l;i++){
32 if (x.a[i]<y.a[i]){
33 x.a[i]+=base;
34 x.a[i+1]--;
35 }
36 x.a[i]-=y.a[i];
37 }
38 while ((x.l>1)&&(!x.a[x.l]))x.l--;
39 return x;
40 }
41 ji mul(ji x,int y){
42 x.a[1]=x.a[1]*y;
43 for(int i=2;i<=x.l;i++){
44 x.a[i]=x.a[i]*y+x.a[i-1]/base;
45 x.a[i-1]%=base;
46 }
47 if (x.a[x.l]>=base){
48 x.a[x.l+1]=x.a[x.l]/base;
49 x.a[x.l]%=base;
50 x.l++;
51 }
52 return x;
53 }
54 ji mul(ji x,ji y){
55 ji ans;
56 ans.l=x.l+y.l-1;
57 memset(ans.a,0,sizeof(ans.a));
58 for(int i=1;i<=x.l;i++)
59 for(int j=1;j<=y.l;j++){
60 ll s=1LL*x.a[i]*y.a[j];
61 ans.a[i+j]+=(ans.a[i+j-1]+s)/base;
62 ans.a[i+j-1]=(ans.a[i+j-1]+s)%base;
63 }
64 if (ans.a[ans.l+1])ans.l++;
65 return ans;
66 }
67 ji div(ji x,int y){
68 int r=0;
69 for(int i=x.l;i;i--){
70 r+=x.a[i];
71 x.a[i]=r/y;
72 r=(r%y)*base;
73 }
74 if ((x.l>1)&&(!x.a[x.l]))x.l--;
75 return x;
76 }
77 void write(ji x){
78 printf("%d",x.a[x.l]);
79 for(int i=x.l-1;i;i--){
80 if (x.a[i]<1000000)printf("0");
81 if (x.a[i]<100000)printf("0");
82 if (x.a[i]<10000)printf("0");
83 if (x.a[i]<1000)printf("0");
84 if (x.a[i]<100)printf("0");
85 if (x.a[i]<10)printf("0");
86 printf("%d",x.a[i]);
87 }
88 }
89 ji div(ji x,ji y){
90 ji l=zero,r=x,mid;
91 while (cmp(l,r)<0){
92 mid=div(add(l,r),2);
93 //write(l),printf(" "),write(r),printf(" "),write(mul(mid,y)),printf("\n");
94 if (cmp(mul(mid,y),x)<0)l=add(mid,one);
95 else r=mid;
96 }
97 return l;
98 }
99 ji gcd(ji x,ji y){
100 int cnt=0,deep=0;
101 while (cmp(x,y)){
102 int p1=(x.a[1]&1),p2=(y.a[1]&1);
103 if ((p1)&&(p2)){
104 if (cmp(x,y)<0)y=dec(y,x);
105 else x=dec(x,y);
106 continue;
107 }
108 if (!p1)x=div(x,2);
109 if (!p2)y=div(y,2);
110 if ((!p1)&&(!p2))cnt++;
111 }
112 ji ans=x;
113 while (cnt--)ans=mul(ans,2);
114 return ans;
115 }
116 int main(){
117 scanf("%d%d%s",&pa,&pb,s);
118 n=strlen(s);
119 zero.l=one.l=one.a[1]=1;
120 ans_mu=one;
121 for(int i=0;i<n;i++)
122 if (s[i]=='H')ans_mu=mul(ans_mu,pa);
123 else ans_mu=mul(ans_mu,pb-pa);
124 pre[0]=ans_mu;
125 for(int i=0;i<n;i++){
126 pre[i+1]=mul(pre[i],pb);
127 if (s[i]=='H')pre[i+1]=div(pre[i+1],pa);
128 else pre[i+1]=div(pre[i+1],pb-pa);
129 }
130 nex[0]=nex[1]=0;
131 for(int i=1,j=0;i<n;i++){
132 while ((j)&&(s[i]!=s[j]))j=nex[j];
133 if (s[i]==s[j])j++;
134 nex[i+1]=j;
135 }
136 for(int i=n;i;i=nex[i])ans_zi=add(ans_zi,pre[i]);
137 ji d=gcd(ans_zi,ans_mu);
138 write(div(ans_zi,d));
139 printf("/");
140 write(div(ans_mu,d));
141 }
[luogu3334]抛硬币的更多相关文章
- 模拟抛硬币(C语言实现)
实现代码: #include<stdio.h> #include<stdlib.h> int heads() { ; } int main(int argc, char *ar ...
- bzoj 4830: [Hnoi2017]抛硬币 [范德蒙德卷积 扩展lucas]
4830: [Hnoi2017]抛硬币 题意:A投a次硬币,B投b次硬币,a比b正面朝上次数多的方案数,模\(10^k\). \(b \le a \le b+10000 \le 10^{15}, k ...
- [HNOI 2017]抛硬币
Description 题库链接 两人抛硬币一人 \(a\) 次,一人 \(b\) 次.记正面朝上多的为胜.问抛出 \(a\) 次的人胜出的方案数. \(1\le a,b\le 10^{15},b\l ...
- bzoj 4830: [Hnoi2017]抛硬币
Description 小A和小B是一对好朋友,他们经常一起愉快的玩耍.最近小B沉迷于**师手游,天天刷本,根本无心搞学习.但是 已经入坑了几个月,却一次都没有抽到SSR,让他非常怀疑人生.勤勉的小A ...
- [AH/HNOI2017]抛硬币
题目描述 小 A 和小 B 是一对好朋友,他们经常一起愉快的玩耍.最近小 B 沉迷于**师手游,天天刷本,根本无心搞学习.但是已经入坑了几个月,却一次都没有抽到 SSR,让他非常怀疑人生.勤勉的小 A ...
- bzoj4830 hnoi2017 抛硬币
题目描述 小 A 和小 B 是一对好朋友,他们经常一起愉快的玩耍.最近小 B 沉迷于**师手游,天天刷本,根本无心搞学习.但是已经入坑了几个月,却一次都没有抽到 SSR,让他非常怀疑人生.勤勉的小 A ...
- luogu P3726 [AH2017/HNOI2017]抛硬币
传送门 我是真的弱,看题解都写了半天,,, 这题答案应该是\(\sum_{i=1}^{a}\binom{a}{i}\sum_{j=0}^{min(b,i-1)}\binom{b}{j}\) 上面那个式 ...
- GMA Round 1 抛硬币
传送门 抛硬币 扔一个硬币,正面概率为0.6.扔这枚硬币666次,正面就得3分,反面就得1分,求总分的方差. 直接套公式$np(1-p)*(X-Y)^2=666*0.6*(1-0.6)*(3-1)^2 ...
- 【BZOJ4830】[HNOI2017]抛硬币(组合计数,拓展卢卡斯定理)
[BZOJ4830][HNOI2017]抛硬币(组合计数,拓展卢卡斯定理) 题面 BZOJ 洛谷 题解 暴力是啥? 枚举\(A\)的次数和\(B\)的次数,然后直接组合数算就好了:\(\display ...
随机推荐
- 学习使用Wpf开源的文本编辑器—smithhtmleditor
前言 本文主要介绍使用Wpf文本编辑器--smithhtmleditor. 编辑器使用 首先新建一个项目WpfEditor. 然后到Codeplex下载smithhtmleditor. 下载地址:ht ...
- centos8安装MySQL8——通过yum
centos8上通过yum安装MySQL,过程简单,不易出错 1.检查系统是否已安装MySQL相关,如果有则全部清除干净 #列出MySQL相关的安装包 rpm -qa | grep mysql #依次 ...
- Visual Studio Docker调试端口设置
一.前言 在Visual Studio 调试程序时,Docker中的容器端口和主机端口映射随机生成,导致每次调试都需要修改前端API接口的地址 二.解决方案 1.修改Docker调试启动参数,找到启动 ...
- dubbo服务架构介绍
Provider: 暴露服务的服务提供方. Consumer: 调用远程服务的服务消费方. Registry: 服务注册与发现的注册中心. Monitor: 统计服务的调用次数和调用时间的监控中心. ...
- C++ 与 Visual Studio 2019 和 WSL(三)
头文件 如果不小心修改了 Linux C/C++ 标准头文件,可以下面这样操作进行恢复: 项目 → 重新扫描解决方案
- Java泛型背后是什么?
文Java中泛型的应用,让大家更好地理解泛型,以及常说的泛型类型擦除是什么概念,举一个简单的例子,如下: 这里可以看出来在代码编写阶段就已经报错了,不能往string类型的集合中添加int类型的数据. ...
- Wireshark 过滤器的使用
符号 例子 = = tcp.port = = 80 过滤出来TCP包含80端口的数据包 != ip.src != 127.0.0.1 ip的原地址不是127.0.0.1过滤出来 > lp.len ...
- vue3.x移动端适配px2rem
1.什么是px2rem px2rem是一个插件能将px自动转换为rem,以适配各种不同的屏幕尺寸.前端开发可以直接使用设计稿量出的尺寸或者蓝湖给出的px进行布局,这样极大的提高了开发效率. 2.前提条 ...
- Java:线程池
Java:线程池 本笔记是根据bilibili上 尚硅谷 的课程 Java大厂面试题第二季 而做的笔记 获取多线程的方法: 实现 Runnable 接口 实现 Callable 接口 实例化 Thre ...
- 欧姆龙PLC HostLink协议整理
欧姆龙PLC HostLink协议整理 1.常用的存储器功能区 CIO: 输入继电器 272 点(17 CH) 0.00-16.15 输出继电器 272 点(17 CH) 100.00-116.1 ...