[CTSC2006]歌唱王国——生成函数

题面

  Bzoj1152

解析

  需要先来一手概率生成函数。

  定义概率生成函数$f(x)=\sum_{i=0}^{\infty}P(Y==i)x^i$,其中$P(Y==i)$表示$Y$这个变量取$i$的概率,容易发现$f(1) = 1$

  对该概率生成函数求导:$f'(x)=\sum_{i=1}^{\infty}P(Y==i)i*x^{i-1}$,那么可以发现$f'(1)$即是$Y$的期望


 

  接下来开始解决这道题。

  设$f_i$表示终止长度为$i$的概率,$F(x)$为其生成函数。设$g_i$表示长度为$i$还未终止的概率,$g_0=1$,$G(x)$为其生成函数。

  考虑$g_i$向$f_{i+1}$与$g_{i+1}$转移,即在长度为$i$的未终止的串后加一个字符:$g_i=f_{i+1}+g_{i+1}$,也即:$$F(x)+G(x)=x*G(x)+1$$

  因为$F'(1)$为所求,因此两边求导:$$F'(x)+G'(x)=x*G'(x)+G(x)$$

  代入$x=1$:$$F'(1)=G(1)$$

  现在只要求出$G(1)$即可

  设目标串串长为$m$,字符集大小为$n$,$a_i=1/0$表示$[1,i]$是否为目标串的一个$border$

  考虑在任意一个未终止串后加上一个目标串都一定可以终止,但可能在加到中间某个字符时就可以终止了,所以枚举真正所需要的串的长度,有方程:$g_i(\frac{1}{n})^m=\sum_{j=1}^{m}a_jf_{i+j}(\frac{1}{n})^{m-j}$,即:$$G(x)(\frac{1}{n})^m*x^m=F(x)\sum_{i=1}^{m}a_i(\frac{1}{n})^{m-i}*x^{m-i}$$

  代入$x=1$:$$G(1)=\sum_{i=1}^m a_i*n^i$$

  $KMP$求出$a$数组即可

  $O(N)$

 代码:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn = 100005, mod = 10000;

inline int read()
{
    int ret, f=1;
    char c;
    while((c=getchar())&&(c<'0'||c>'9'))if(c=='-')f=-1;
    ret=c-'0';
    while((c=getchar())&&(c>='0'&&c<='9'))ret=(ret<<3)+(ret<<1)+c-'0';
    return ret*f;
}

int add(int x, int y)
{
    return x + y < mod? x + y: x + y - mod;
}

int n, m, T, a[maxn], fail[maxn], pw[maxn];

void KMP()
{
    int t;
    for(int i = 2; i <= m; ++i)
    {
        t = fail[i-1];
        while(t && a[t+1] != a[i])    t = fail[t];
        fail[i] = ((a[t+1] == a[i])? t + 1: 0);
    }
}

int main()
{
    n = read(); T = read();
    pw[0] = 1;
    for(int i = 1; i <= 100000; ++i)
        pw[i] = pw[i-1] * n % mod;
    int ans;
    while(T --)
    {
        m = read();
        for(int i = 1; i <= m; ++i)
            a[i] = read();
        KMP();
        ans = 0;
        for(int i = m; i; i = fail[i])
            ans = add(ans, pw[i]);
        printf("%d%d%d%d\n", ans / 1000, (ans / 100) % 10, (ans / 10) % 10, ans % 10);
    }
    return 0;
}
View Code
posted @ 2020-04-05 23:32  Mr_Joker  阅读(189)  评论(0编辑  收藏  举报