(数据范围的公式渲染有一些问题,大概是$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]抛硬币的更多相关文章

  1. 模拟抛硬币(C语言实现)

    实现代码: #include<stdio.h> #include<stdlib.h> int heads() { ; } int main(int argc, char *ar ...

  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. [HNOI 2017]抛硬币

    Description 题库链接 两人抛硬币一人 \(a\) 次,一人 \(b\) 次.记正面朝上多的为胜.问抛出 \(a\) 次的人胜出的方案数. \(1\le a,b\le 10^{15},b\l ...

  4. bzoj 4830: [Hnoi2017]抛硬币

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

  5. [AH/HNOI2017]抛硬币

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

  6. bzoj4830 hnoi2017 抛硬币

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

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

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

  8. GMA Round 1 抛硬币

    传送门 抛硬币 扔一个硬币,正面概率为0.6.扔这枚硬币666次,正面就得3分,反面就得1分,求总分的方差. 直接套公式$np(1-p)*(X-Y)^2=666*0.6*(1-0.6)*(3-1)^2 ...

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

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

随机推荐

  1. Java基础语法(语法、位运算、JavaDoc等)

    一.注释.标识符.关键字 1.注释(comments) 平时我们编写代码,在代码量比较少的时候,我们还可以看懂自己编写的代码,但是当项目结构一旦复杂起来,我们就需要用到注释了! 注释并不会被程序执行, ...

  2. InstallSheild相关

    一.关于使用InstallSheild制作安装包的总结. 1.定制化制作需要了解InstallScript语法,相关资料可以去网上查找,后续提供比较好的资料. 2.有些软件运行是需要一些环境的,譬如使 ...

  3. 接口自动化-Python3+request上传文件,发送multipart/form-data编码

    1.安装requests_toolbelt   pip install requests-toolbelt 2.发送文件中的数据 from requests_toolbelt import Multi ...

  4. 不会SQL也能做数据分析?浅谈语义解析领域的机会与挑战

    笔者按: 在第5次AI TIME PhD Debate上,笔者邀请了部分国内外语义解析领域的杰出华人学者共话语义解析的过去,现状和未来.本博客为笔者根据视频讨论总结的干货整理.对原视频感兴趣的同学可以 ...

  5. 第32篇-解析interfacevirtual字节码指令

    在前面介绍invokevirtual指令时,如果判断出ConstantPoolCacheEntry中的_indices字段的_f2属性的值为空,则认为调用的目标方法没有连接,也就是没有向Constan ...

  6. camera HSYNC:VSYNC

    HSYNC:行锁存,换行信号VSYNC:祯锁存,换页信号 320×240的屏,每一行需要输入320个脉冲来依次移位.锁存进一行的数据,然后来个HSYNC 脉冲换一行:这样依次输入240行之后换行同时来 ...

  7. 设计的MOS管三极管简单开关电路驱动能力不够1

    您需要 登录 才可以下载或查看,没有帐号?注册 x . ?& P' U5 r/ ~& `: B 用AOD409设计的开关电路为什么驱动能力不够,请大家帮忙分析一下原因啊.这个电路作用就 ...

  8. STM32中按键中断分析

    在按键学习中,我们有用到查询的方法来判断按键事件是否发生,这种查询按键事件适用于程序工作量较少的情况下,一旦程序中工作量较大较多,则势必影响程序运行的效率,为了简化程序中控制的功能模块的执行时间,引入 ...

  9. .NET 5 全自动分表组件,.NET 分表方案 ,分表架构与设计

    一.疑问&目的 1.1 分表使用场景 (1)可扩展架构设计,比如一个ERP用5年不卡,到了10就卡了因为数据太多了,这个时候很多人都是备份然后清空数据,这个工作大并且麻烦,以前的数据很难在使用 ...

  10. Ubuntu 16.04 菜单栏 换位置 挪到左边 挪到下边

    Ubuntu菜单栏的位置可以调 到左侧 或者底部 调整到底部 $ gsettings set com.canonical.Unity.Launcher launcher-position Bottom ...