[Contest20170910]string
给定一个由且仅由字符$'H','T'$构成的字符串$S$
给定一个最初为空的字符串$T$,每次随机地在$T$的末尾添加$'H'$或者$'T'$
问当$S$为$T$的后缀时,在末尾添加字符的期望次数
妙啊!
设$f_i(0\leq i \leq n-1)$表示(在$T$的末尾匹配$S_{1\cdots i}$)到(在$T$的末尾匹配$S_{1\cdots i+1}$)期望添加多少个字符
①有$\frac12$的概率直接匹配,需要添加$1$个字符
②另外$\frac12$的概率失配,需要添加更多字符
⑨
我们来看看②,为了解决问题,我们引入$go_{i,j}(0\leq i\leq n-1,j\in\{'H','T'\})$表示当已经在$T$的末尾匹配$S_{1\cdots i}$时在$T$的末尾添加字符$j$能匹配到的最远位置
首先假设我们计算好了$go_{1\cdots i-1,'H'\cdots'T'}$,想计算$go_{i,'H'\cdots'T'}$
若$S_{i+1}='H'$,则$go_{i,'H'}=i+1$,$go_{i,'T'}=go_{next_i,'T'}$
若$S_{i+1}='T'$,则$go_{i,'H'}=go_{next_i,'H'}$,$go_{i,'T'}=i+1$
其中$next_i$代表最大的$k\lt i$使得$S_{1\cdots k}=S_{i-k+1\cdots i}$,与kmp中的$next$含义相同
有了$go_{i,j}$,我们现在可以解决②了
失配之后用$go_{i,j}$找到再次匹配的位置,然后一路添加字符直到到达$S_{i+1}$
若$S_{i+1}='H'$,则$f_i=\frac12+\frac12(1+\sum\limits_{go_{i,'T'}\leq j\leq i}f_j)$
整理得$f_i=2+\sum\limits_{go_{i,'T'}\leq j\leq i-1}f_j$
若$S_{i+1}='T'$,则$f_i=\frac12+\frac12(1+\sum\limits_{go_{i,'H'}\leq j\leq i}f_j)$
整理得$f_i=2+\sum\limits_{go_{i,'H'}\leq j\leq i-1}f_j$
综上,我们先用kmp预处理出$next_i$,然后用$next_i$预处理出$go_{i,j}$,最后用$go_{i,j}$算出$f_i$
递推中的$\sum$边算边累加即可,最后的答案为$f_0+f_1+\cdots+f_{n-1}$
#include<stdio.h>
#include<string.h>
#define mod 1000000007
char s[1000010];
int pi[1000010],f[1000010],sumf[1000010],go[1000010][2],n,i,j;
int main(){scanf("%s",s+1);n=strlen(s+1);pi[1]=0;j=0;for(i=2;i<=n;i++){while(j&&s[i]!=s[j+1])j=pi[j];if(s[i]==s[j+1])j++;pi[i]=j;}//0:H 1:Tfor(i=0;i<n;i++){if(s[i+1]=='H'){go[i][0]=i+1;go[i][1]=go[pi[i]][1];}else{go[i][0]=go[pi[i]][0];go[i][1]=i+1;}}f[0]=2;sumf[0]=2;for(i=1;i<n;i++){if(s[i+1]=='H')f[i]=(2+sumf[i-1]-(go[i][1]?sumf[go[i][1]-1]:0))%mod;elsef[i]=(2+sumf[i-1]-(go[i][0]?sumf[go[i][0]-1]:0))%mod;sumf[i]=(sumf[i-1]+f[i])%mod;}printf("%d",(sumf[n-1]+mod)%mod);
}
转载于:https://www.cnblogs.com/jefflyy/p/7501277.html
[Contest20170910]string相关推荐
- Java知识——精华总结
Java知识--精华总结 一.java概述与基础知识 1.何为编程? 编程就是让计算机为解决某个问题而使用某种程序设计语言编写程序代码,并最终得到结果的过程. 为了使计算机能够理解人的意图,人类就必须 ...
- mybatis查询报错:com.mysql.cj.exceptions.DataConversionException: Cannot determine value type from string
mybatis查询报错: com.mysql.cj.exceptions.DataConversionException: Cannot determine value type from strin ...
- Go 学习笔记(60)— Go 第三方库之 go-redis(初始化 redis、操作 string、操作 list、操作 set、操作 hset)
1. 第三方库 go-redis 因为 Go 标准库中是没提供 redis 的库,所以我们选择用 go-redis 这个第三方库.源码地址为 https://github.com/go-redis/r ...
- Redis 笔记(03)— string类型(设置key、获取key、设置过期时间、批量设置获取key、对key进行加减、对key值进行追加、获取value子串)
字符串 string 是 Redis 最简单的数据结构.Redis 所有的数据结构都是以唯一的 key 字符串作为名称,然后通过这个唯一 key 值来获取相应的 value 数据.不同类型的数据结构的 ...
- python中的raw string的使用
背景 我们经常需要使用raw string,在应用过程中,比如要使字符串中带一些转义字符或者其他的一些符号,我们就需要保持我们的字符成为raw string. 实例 输入 s = 'fadfafa\n ...
- Java中如何实现Date与String之间的数据类型转换
String 数据类型转换成 Date String inputDate = "2021-04-11";Date outputDate = null;SimpleDateForma ...
- C++ string字符串的比较是否相等
C++ string字符串的比较是否相等 可以使用compare 也可以使用"==" 1 使用比较运算符 == #include <iostream> #include ...
- python string 转bytes 以及bytes 转string
string转 bytes 使用 encode str_a = "Python" str_bytes = str_a.encode() # encode默认编码方式是utf-8 所 ...
- TypeError: string argument without an encoding
这个错误是把string 类型转byte类型的时候出现的问题 下面就会报错 print(bytes(str_a)) 修改为如下就好了 print(bytes(str_a.encode())) 或者就不 ...
最新文章
- 2022-2028年中国铅锌精矿粉行业市场研究及前瞻分析报告
- 双绞线,同轴电缆和光纤电缆之间的区别—Vecloud微云
- 在MSBuild.exe中使用条件编译(Conditional Compile)
- 下坠的小鸟(flappy bird)速算版
- LeetCode:Unique Binary Search Trees
- @Autowired自动注入
- XML Schema全接触 (这里主要介绍W3C的Schema标准语法)
- 调用支付jsapi缺少参数:total_fee_小程序支付问题怎么解决?
- 分布式数据流计算系统的数据缓存技术综述
- python爬虫程序框架的理论是什么_Python网络爬虫(scrapy框架简介和基础应用)
- php+mysql案例含源码_[源码和文档分享]基于PHP和MYSQL数据库实现的失物招领系统...
- 了解Linux操作系统的引导过程
- 程序开发类本科论文结构【2022年修改】
- 王者荣耀英雄测试用例
- docker与宿主机通信
- 深入理解java虚拟机-第三版-周明志 Java虚拟机规范(java se 8) pdf
- cpu.h-栈的宏定义-满减栈
- wx2540h配置教程_求高手解决H3C无线网络 WX3024E和无线AP设备之间的详细配置命令!...
- Selenium:动态页面模拟点击
- Json字符串转JsonObject例子