【BZOJ1152】歌唱王国(生成函数,KMP)
【BZOJ1152】歌唱王国(生成函数,KMP)
题面
题解
根据\(YMD\)论文来的QwQ。
首先大家都知道普通型生成函数是\(\displaystyle \sum_{i=0}^{\infty}a_ix^i\),类似的定义概率生成函数\(\displaystyle F(x)=\sum_{i=0}^\infty P(X=i)x^i\)。其中\(P(X=i)\)表示\(X\)这个随机变量为\(i\)的概率。
那么我们可以知道几个结论:\(\displaystyle F(1)=\sum_{i=0}^\infty P(X=i)=1\),这个结论很显然。
如果我们要求解期望,显然期望等于\(\displaystyle \sum_{i=0}^{\infty}iP(X=i)\)。
我们发现\(\displaystyle F'(x)=\sum_{i=1}^\infty iP(X=i)x^{i-1}\),那么我们要求解的期望就是\(F'(1)\)。
回到题目。
我们设\(f_i\)表示终止长度为\(i\)的概率,\(F(x)\)为其概率生成函数,那么要求解的就是\(F'(1)\)。
设\(g_i\)表示当前长度为\(i\)且还未结束的概率,\(G(x)\)为其普通型生成函数,那么我们可以得到:
\]
这个式子什么意思呢?首先右侧的\(1+G(x)x\)表示在当前序列后面随机加上一个字符,要加一的愿意是\(g_0=1\)。那么随机加完一个字符后,结束的概率是变成了\(F(x)\),未结束的概率是\(G(x)\),所以得到了这个等式。
设\(a_i\)表示\(A[1..i]\)是否是串\(A\)的\(border\),那么我们可以得到:
\]
等式左侧的含义是在当前未结束的串的后面直接接上目标串,那么这样一定会结束。
右侧的含义是因为前面的随机串中可能已经匹配了一部分的长度,导致在匹配了一半此时就已经结束了。
那么我们插入了一半就结束了,并且此时我们插入的一定是一段前缀,因此只有可能当这个位置是\(border\)时才可能结束。
那么强制在这个\(border\)时会结束,等价于我们钦定了随机串的最后\(L-i\)位。那么就得到了右边的式子。
我们要求解的东西是\(F'(1)\),
首先第一个式子可以写成:
\]
化简得到\(F'(1)=G(1)\)
然后令\(x=1\)带入到第二个式子中,可以得到:
\]
那么只需要\(KMP\)求解\(border\)就行了。
#include<iostream>
#include<cstdio>
using namespace std;
#define MOD 10000
#define MAX 100100
inline int read()
{
int x=0;bool t=false;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=true,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return t?-x:x;
}
int n,T,pw[MAX],s[MAX],nt[MAX];
int main()
{
n=read();T=read();
pw[0]=1;for(int i=1;i<MAX;++i)pw[i]=1ll*pw[i-1]*n%MOD;
while(T--)
{
int m=read(),ans=0;
for(int i=1;i<=m;++i)s[i]=read();
for(int i=2;i<=m;++i)
{
int t=nt[i-1];
while(t&&s[t+1]!=s[i])t=nt[t];
if(s[t+1]==s[i])++t;
nt[i]=t;
}
for(int i=m;i;i=nt[i])ans=(ans+pw[i])%MOD;
printf("%04d\n",ans);
}
return 0;
}
【BZOJ1152】歌唱王国(生成函数,KMP)的更多相关文章
- 【题解】歌唱王国(概率生成函数+KMP)+伦讲的求方差
[题解]歌唱王国(概率生成函数+KMP)+伦讲的求方差 生成函数的本质是什么呀!为什么和It-st一样神 设\(f_i\)表示填了\(i\)个时候停下来的概率,\(g_i\)是填了\(i\)个的时候不 ...
- [CTSC2006]歌唱王国
[CTSC2006]歌唱王国 Tags:题解 题意 链接:在空串后不断随机添加字符,直到出现串\(S_i\)为止.求最终串的期望长度.\(\sum |S_i|\le 5*10^6\) 题解 以下内容来 ...
- bzoi1152 [CTSC2006]歌唱王国Singleland
[CTSC2006]歌唱王国Singleland Time Limit: 30 Sec Memory Limit: 162 MB Description 在歌唱王国,所有人的名字都是一个非空的仅包含整 ...
- P4548-[CTSC2006]歌唱王国【概率生成函数,KMP】
正题 题目链接:https://www.luogu.com.cn/problem/P4548 题目大意 \(t\)次询问,给出一个长度为\(m\)的串\(S\)和一个空串\(T\),每次在\(T\)后 ...
- 洛谷P4548 [CTSC2006]歌唱王国(概率生成函数)
题面 传送门 给定一个长度为\(L\)的序列\(A\).然后每次掷一个标有\(1\)到\(m\)的公平骰子并将其上的数字加入到初始为空的序列\(B\)的末尾,如果序列B中已经出现了给定序列\(A\), ...
- Luogu4548 CTSC2006 歌唱王国 概率生成函数、哈希
传送门 orz ymd 考虑构造生成函数:设\(F(x) = \sum\limits_{i=0}^\infty f_ix^i\),其中\(f_i\)表示答案为\(i\)的概率:又设\(G(x) = \ ...
- 洛谷 P4548 - [CTSC2006]歌唱王国(概率生成函数)
洛谷题面传送门 PGF 入门好题. 首先介绍一下 PGF 的基本概念.对于随机变量 \(X\),满足 \(X\) 的取值总是非负整数,我们即 \(P(v)\) 表示 \(X=v\) 的概率,那么我们定 ...
- luogu P4548 [CTSC2006]歌唱王国
传送门 这题\(\mathrm{YMD}\)去年就讲了,然而我今年才做(捂脸) 考虑生成函数,设\(f_i\)表示最终串长为\(i\)的概率,其概率生成函数为\(F(x)=\sum f_ix^i\), ...
- BZOJ 1152 歌唱王国
题目传送门 分析: 这道题很神仙,我们给出低配版解法和高配版解法2333 低配版: 首先知道这样一个公式...(证明去高配版) 当一个字符串S其中S [ 1 , i ] = S [ n - i + 1 ...
随机推荐
- Volterra方程的不动点
- win64位安装python-mysqldb1.2.3
在其他版本的mysqldb里面时间查询有问题最后确定还是在 1.2.5 版本下来解决,需要解决的问题就是这个:“Cannot open include file: 'config-win.h': No ...
- node学习: package.json
package.json 定义了这个项目所需要的各种模块,以及项目的配置信息(比如名称.版本.许可证等元数据) 1.创建 package.json npm init npm init –yes 2.p ...
- [转帖]Linux 硬件和系统配置查看命令小结
https://blog.csdn.net/strongwangjiawei/article/details/8208825 转帖了不少 发现自己记住的还是不多.. Linux 硬件和系统配置查看命令 ...
- .Net批量插入数据
1. 一般我们普通数据插入是这样的: 现在我们写一个控制台程序用常规办法添加10000条数据. //以下是批量插入数据的办法 //连接字符串 string str = "Server=.;D ...
- Ubuntu18.04安装mysql5.7
Ubuntu18.04安装mysql5.7 1.1安装 首先执行下面三条命令: # 安装mysql服务 sudo apt-get install mysql-server # 安装客户端 sudo a ...
- mysql 常用字段类型
tinyint[(m)] [unsigned] [zerofill] 1字节 极小整数,数据类型用于保存一些范围的整数数值范围: 有符号: -128 - 127. 无符号: - 255 特别的: My ...
- kubernetes资源类别介绍
类别 名称 资源对象 Pod.ReplicaSet.ReplicationController.Deployment.StatefulSet.DaemonSet.Job.CronJob.Horizon ...
- DAY04、流程控制if、while、for
一.if 判断 语法一: if 条件: # 以下是上一条if 的子代码块 print(子代码1) print(子代码2) print(子代码3) 示例: # 路边飘过一个生物,要不要表白? sex = ...
- opencv imdecode和imencode用法
主要是对内存数据自动编解码 string fname = "D:/image.jpg"; //! 以二进制流方式读取图片到内存 FILE* pFile = fopen(fname. ...