概率生成函数(Probability Generating Function,PGF,通常情况下以随机变量 X X X 在非负整数集合 N \mathbb{N} N 上为前提),顾名思义,即为概率的生成函数,或者说,如果数列 { p n } \{p_n\} {pn} 满足 P ( X = i ) = p i P(X=i)=p_i P(X=i)=pi(即 { p n } \{p_n \} {pn} 为 X X X 的概率质量函数 PMF 所构成的数列),那么称 { p n } \{p_n\} {pn} 的普通生成函数为 X X X 的概率生成函数:(显然 n ∈ N n\in \mathbb{N} n∈N)
F X ( x ) = ∑ i = 0 + ∞ P ( X = i ) x i F_X(x)=\sum^{+\infty}_{i=0}P(X=i)x^i FX(x)=i=0∑+∞P(X=i)xi
其中, P ( X = i ) P(X=i) P(X=i) 表示随机变量 X X X 为 i i i 的概率。
显然 F X ( 1 ) = ∑ i = 0 + ∞ P ( X = i ) = 1 F_X(1)=\sum\limits^{+\infty}_{i=0} P(X=i)=1 FX(1)=i=0∑+∞P(X=i)=1(概率之和为 1 1 1);
对 F X ( x ) F_X(x) FX(x) 求导可以得到 F X ′ ( x ) = ∑ i = 0 + ∞ i P ( X = i ) x i − 1 F_X'(x)=\sum\limits^{+\infty}_{i=0}iP(X=i)x^{i-1} FX′(x)=i=0∑+∞iP(X=i)xi−1,那么此时 F X ′ ( 1 ) = ∑ i = 0 + ∞ i P ( X = i ) = E ( X ) F_X'(1)=\sum\limits^{+\infty}_{i=0} iP(X=i)=E(X) FX′(1)=i=0∑+∞iP(X=i)=E(X) ( X X X 的期望为 E ( X ) E(X) E(X));
对 F X ( x ) F_X(x) FX(x) 求二阶导可得 F X ′ ( x ) = ∑ i = 0 + ∞ i ( i − 1 ) P ( X = i ) x i − 2 F_X'(x)=\sum\limits^{+\infty}_{i=0}i(i-1)P(X=i)x^{i-2} FX′(x)=i=0∑+∞i(i−1)P(X=i)xi−2,那么 F X ′ ′ ( 1 ) = ∑ i = 0 + ∞ i 2 P ( X = i ) − ∑ i = 0 + ∞ i P ( X = i ) = E ( X 2 ) − E ( X ) F_X''(1)=\sum\limits^{+\infty}_{i=0} i^2P(X=i)-\sum\limits^{+\infty}_{i=0} iP(X=i)=E(X^2)-E(X) FX′′(1)=i=0∑+∞i2P(X=i)−i=0∑+∞iP(X=i)=E(X2)−E(X) ,所以 E ( X 2 ) = F X ′ ′ ( 1 ) + E ( X ) = F X ′ ′ ( 1 ) + F X ′ ( 1 ) E(X^2)=F_X''(1)+E(X)=F_X''(1)+F_X'(1) E(X2)=FX′′(1)+E(X)=FX′′(1)+FX′(1),可得 D ( X ) = E ( X 2 ) − ( E ( X ) ) 2 = F X ′ ′ ( 1 ) + F X ′ ( 1 ) ( 1 − F X ′ ( 1 ) ) D(X)=E(X^2)-(E(X))^2=F_X''(1)+F_X'(1)(1-F_X'(1)) D(X)=E(X2)−(E(X))2=FX′′(1)+FX′(1)(1−FX′(1))( X X X 的方差为 D ( X ) D(X) D(X));
这些性质可以用来简化一些推导 QwQ。
字符集大小为 n n n,处理 t t t 组数据,每组数据给出一个长度为 m m m 的字符集 S S S,空串 T T T 每次随机加入一个字符,直到 T T T 中出现 S S S 停止,求 T T T 停止时长度的期望。
显然不能直接硬算,先设变量 Y Y Y 表示停止时 T T T 的长度,再引入两个概率生成函数 f ( x ) f(x) f(x)、 g ( x ) g(x) g(x) 分别表示 Y = i Y=i Y=i 的概率和 Y > i Y>i Y>i 的概率,即 f ( x ) = ∑ i = 0 + ∞ P ( Y = i ) x i f(x)=\sum^{+\infty}_{i=0}P(Y=i)x^i f(x)=∑i=0+∞P(Y=i)xi, g ( x ) = ∑ i = 0 + ∞ P ( Y > i ) x i g(x)=\sum^{+\infty}_{i=0}P(Y>i)x^i g(x)=∑i=0+∞P(Y>i)xi,为了方便我们分别用 f i f_i fi、 g i g_i gi 表示 f f f、 g g g 的 i i i 次项的系数,那么 f i f_i fi 就表示在第 i i i 次添加停止的概率, g i g_i gi 就表示在第 i i i 次添加仍未停止的概率,最终我们要求的期望 E ( Y ) = f ′ ( 1 ) E(Y)=f'(1) E(Y)=f′(1),接下来的任务便是找式子求期望了。
首先我们可以根据 f f f、 g g g 的定义来确定一个递推式,因为 Y Y Y 一定是一个正整数,所以 Y > i Y>i Y>i 等价于 Y ≥ i + 1 Y\ge i+1 Y≥i+1,手动分类讨论一下(等于和大于的情况)可得 g i = f i + 1 + g i + 1 g_i=f_{i+1}+g_{i+1} gi=fi+1+gi+1,整理成生成函数得到 x g ( x ) + 1 = f ( x ) + g ( x ) xg(x)+1=f(x)+g(x) xg(x)+1=f(x)+g(x)( + 1 +1 +1 是补上 g 0 = 1 g_0=1 g0=1 的项),由于我们要求 f ′ ( 1 ) f'(1) f′(1),那么就可以用 g g g 来表示 f f f,即
f ( x ) = ( x − 1 ) g ( x ) + 1 f(x)=(x-1)g(x)+1 f(x)=(x−1)g(x)+1
求个导可得 f ′ ( x ) = g ( x ) + ( x − 1 ) g ′ ( x ) f'(x)=g(x)+(x-1)g'(x) f′(x)=g(x)+(x−1)g′(x),最终我们有 f ′ ( 1 ) = g ( 1 ) f'(1)=g(1) f′(1)=g(1),皆大欢喜 ,这意味着只要我们能求出 g ( 1 ) g(1) g(1) 就能得到答案了。
接下来我们又设一个数列 h i h_i hi 表示在第 i i i 次操作后仍未结束,强制性地给 T T T 随机加上长度为 m m m 的串 S S S 的概率(强制表示可能有尚未加满 m m m 个字符就已经出现了 S S S 的情况,但仍然继续加字符直到加满了 m m m 个字符,并且根据定义,加入的 m m m 个字符能组成串 S S S),那么就相当于我们在 g i g_i gi 的情况下强制加了 m m m 个字符,于是能得到 h i = g i × n − m h_i=g_i\times n^{-m} hi=gi×n−m。
但同时我们能发现此时能够满足 h i h_i hi 条件的 Y Y Y 应该有 i < Y ≤ i + m i
结合这两种 h i h_i hi 的求法,可得到 g i × n − m = ∑ t = 1 m p d ( t ) f y × n t − m = n − m × ( ∑ t = 1 m p d ( t ) f y × n t ) g_i\times n^{-m}=\sum\limits^m_{t=1} pd(t)f_y\times n^{t-m}=n^{-m}\times\big(\sum\limits^m_{t=1} pd(t)f_y\times n^t\big) gi×n−m=t=1∑mpd(t)fy×nt−m=n−m×(t=1∑mpd(t)fy×nt),又知道 y = i + t y=i+t y=i+t,于是 g i = ∑ t = 1 m p d ( t ) f i + t × n t g_i=\sum\limits^m_{t=1} pd(t)f_{i+t}\times n^t gi=t=1∑mpd(t)fi+t×nt,转化为生成函数形式:
x m g ( x ) = ∑ t = 1 m x m − t f ( x ) p d ( t ) × n t x^{m}g(x)=\sum^m_{t=1}x^{m-t}f(x)pd(t)\times n^t xmg(x)=t=1∑mxm−tf(x)pd(t)×nt
代入可得 g ( 1 ) = ∑ t = 1 m f ( 1 ) p d ( t ) × n t = ∑ t = 1 m p d ( t ) × n t g(1)=\sum\limits^m_{t=1}f(1)pd(t)\times n^t=\sum\limits^m_{t=1}pd(t)\times n^t g(1)=t=1∑mf(1)pd(t)×nt=t=1∑mpd(t)×nt,综上,最终的答案便为 ∑ t = 1 m p d ( t ) × n t \sum\limits^m_{t=1}pd(t)\times n^t t=1∑mpd(t)×nt,直接上 KMP 就做完啦,完结撒花✿✿ヽ(°▽°)ノ✿。
#include
#define mod 10000
#define File(xxx) freopen(xxx".in","r",stdin),freopen(xxx".out","w",stdout)
using namespace std;
typedef long long LL;
const int N = 1e5+5;
int k, t, n, nxt[N], a[N], vis[N], pw[N], ans;
template <typename T> inline void debug(T x) { cerr<<x<<'\n'; }
template <typename T, typename ...T_> inline void debug(T x, T_ ...p) { cerr<<x<<' ', debug(p...); }
template <typename T> void read(T& x) {
x = 0; int f = 0; char c = getchar();
while(c < '0' || c > '9') f |= (c == '-'), c=getchar();
while(c >= '0' && c <= '9') x=(x<<1)+(x<<3)+(c^48), c=getchar();
x=(f ? -x : x);
}
int lne; char put[105];
template <typename T> void write(T x, char ch) {
lne = 0; if(x < 0) putchar('-'), x=-x;
do { put[++lne]=x%10, x/=10; } while(x);
while(lne) putchar(put[lne--]^48);
putchar(ch);
}
int upd(int x) {
return (x >= mod ? x-mod : x);
}
signed main() {
read(k), read(t);
pw[0]=1;
for(int i = 1; i <= 100000; ++i)
pw[i]=1LL*pw[i-1]*k%mod;
while(t--) {
read(n);
ans=0;
for(int i = 1; i <= n; ++i)
read(a[i]), vis[i]=0;
for(int i = 2, j = 0; i <= n; ++i) {
while(j && a[j+1] != a[i]) j=nxt[j];
if(a[j+1] == a[i]) ++j;
nxt[i]=j;
}
int now = n;
while(now)
ans=upd(ans+pw[now]), now=nxt[now];
if(ans < 1000) putchar('0');
if(ans < 100) putchar('0');
if(ans < 10) putchar('0');
write(ans, '\n');
}
return 0;
}