F
(
x
)
=
∑
i
≥
0
P
(
X
=
i
)
x
i
F(x)=\sum_{i\ge0}P(X=i)x^i
F(x)=i≥0∑P(X=i)xi
显然有
F
(
1
)
=
1
F(1)=1
F(1)=1
概率生成函数的应用之一就是如果按照上面的定义,则
X
X
X 的期望为
F
′
(
1
)
F'(1)
F′(1)
方差为
F
′
′
(
1
)
+
F
′
(
1
)
−
(
F
′
(
1
)
)
2
F''(1)+F'(1)-(F'(1))^2
F′′(1)+F′(1)−(F′(1))2
回到原问题,设随机变量
X
X
X 表示插入多少个字符之后匹配到模式串,其概率生成函数为
F
(
x
)
F(x)
F(x)
g
i
g_i
gi 表示插入
i
i
i 个字符之后没有匹配到模式串的概率,其一般生成函数为
G
(
x
)
G(x)
G(x)
可以推出两点性质
F
(
x
)
+
G
(
x
)
=
x
G
(
x
)
+
1
F(x)+G(x)=xG(x)+1
F(x)+G(x)=xG(x)+1
解释:
x
G
(
x
)
+
1
xG(x)+1
xG(x)+1 的第
i
i
i (
i
>
0
i>0
i>0 )项实际上是表示插入
i
−
1
i-1
i−1 个字符后没有匹配成功的概率
而插入
i
−
1
i-1
i−1 个字符后没有匹配成功,就相当于插入
i
i
i 个字符之后匹配成功或失败
和
F
(
x
)
+
G
(
x
)
F(x)+G(x)
F(x)+G(x) 的第
i
i
i (
i
>
0
i>0
i>0 )项正好对应
而
F
(
x
)
F(x)
F(x) 的第
0
0
0 项为
0
0
0 ,
G
(
x
)
G(x)
G(x) 的第
0
0
0 项为
1
1
1
G
(
x
)
×
(
1
n
x
)
m
=
∑
i
=
1
m
a
i
×
F
(
x
)
×
(
1
n
x
)
m
−
i
G(x)\times(\frac 1nx)^m=\sum_{i=1}^ma_i\times F(x)\times (\frac 1nx)^{m-i}
G(x)×(n1x)m=i=1∑mai×F(x)×(n1x)m−i
上面
n
n
n 表示字符集大小,
m
m
m 表示模式串长度,
a
i
a_i
ai 表示模式串的长度为
i
i
i 的前缀和长度为
i
i
i 的后缀是否相等(可用 KMP 求出),相等则为
1
1
1 ,不相等则为
0
0
0
让我们来解释下这个看上去没有实际含义的式子
如果我们现在插入了一些字符,但没有匹配成功
那么如果把长度为
m
m
m 的模式串直接追加在我们已经插入的字符后面,就一定能匹配成功,这对应了等号左边。等号左边多项式
i
+
m
i+m
i+m 次项的意义可以看作匹配成功后不结束操作,但需要满足在插入
i
i
i 个字符时不能匹配成功,在插入
i
+
m
i+m
i+m 个字符时恰好长度为
m
m
m 的后缀与模式串匹配成功的概率
分析一下等号右边
i
+
m
i+m
i+m 次项的含义
∑
j
=
1
m
a
j
P
(
X
=
i
+
j
)
(
1
n
)
m
−
j
\sum_{j=1}^ma_jP(X=i+j)(\frac1n)^{m-j}
j=1∑majP(X=i+j)(n1)m−j
枚举
j
j
j 就相当于枚举第一次匹配成功时已经插入了
i
+
j
i+j
i+j 个字符
然后还要再插入
m
−
j
m-j
m−j 个字符,使得当插入的总字符数达到
i
+
m
i+m
i+m 时再次匹配成功
这时候就必须满足模式串的长度为
j
j
j 的前缀和长度为长度为
j
j
j 的后缀相等
而
(
1
n
)
m
−
j
(\frac 1n)^{m-j}
(n1)m−j 就表示接下来插入的
m
−
j
m-j
m−j 个字符必须是模式串的后缀
解释完毕
对
F
(
x
)
+
G
(
x
)
=
x
G
(
x
)
+
1
F(x)+G(x)=xG(x)+1
F(x)+G(x)=xG(x)+1 两边同时求导
F
′
(
x
)
+
G
′
(
x
)
=
x
G
′
(
x
)
+
G
(
x
)
F'(x)+G'(x)=xG'(x)+G(x)
F′(x)+G′(x)=xG′(x)+G(x)
现在我们要求
F
′
(
1
)
F'(1)
F′(1) ,由上面得出:
F
′
(
1
)
=
G
(
1
)
F'(1)=G(1)
F′(1)=G(1)
于是
F
′
(
1
)
=
n
m
∑
i
=
1
m
a
i
×
F
(
1
)
×
(
1
n
)
m
−
i
F'(1)=n^m\sum_{i=1}^ma_i\times F(1)\times(\frac 1n)^{m-i}
F′(1)=nmi=1∑mai×F(1)×(n1)m−i
=
∑
i
=
1
m
a
i
×
n
i
=\sum_{i=1}^ma_i\times n^i
=i=1∑mai×ni
所以答案为
∑
i
=
1
m
a
i
×
n
i
\sum_{i=1}^ma_i\times n^i
i=1∑mai×ni
于是我们就做完了 ,是不是很简单
Code
#include<cmath>#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#define For(i, a, b) for (i = a; i <= b; i++)inlineintread(){int res =0;bool bo =0;char c;while(((c =getchar())<'0'|| c >'9')&& c !='-');if(c =='-') bo =1;else res = c -48;while((c =getchar())>='0'&& c <='9')
res =(res <<3)+(res <<1)+(c -48);return bo ?~res +1: res;}constint N =1e5+5, ZZQ =1e4;int n, T, m, pw[N], s[N], nxt[N];voidwork(){int i, j =0, ans =0;
m =read();
For (i,1, m) s[i]=read();
For (i,2, m){while(j && s[j +1]!= s[i]) j = nxt[j];if(s[j +1]== s[i]) j++;
nxt[i]= j;}
i = m;while(i) ans =(ans + pw[i])% ZZQ, i = nxt[i];printf("%04d\n", ans);}intmain(){int i;
n =read(); T =read();
pw[0]=1;
For (i,1,100000) pw[i]= pw[i -1]* n % ZZQ;while(T--)work();return0;}