[CTSC2006]歌唱王国

[CTSC2006]歌唱王国

Tags:题解


题意

链接:在空串后不断随机添加字符,直到出现串\(S_i\)为止。求最终串的期望长度。\(\sum |S_i|\le 5*10^6\)

题解

以下内容来自\(YMD\)的2018年集训队论文
很奇怪的生成函数题:
\(f[i]\)表示串最终长度为\(i\)的概率,\(g[i]\)表示到达长度\(i\)还没有结束的概率。分别对应生成函数\(F(x),G(x)\)。最后要求的就是\(F'(1)\)(求导,相当于每个概率都乘上了指数也就是长度,变成了期望)。

会有两个式子:$$G(x)x+1=F(x)+G(x)$$$$G(x)(\frac{1}{m}x)L=\sum_{i=1}a_iF(x)(\frac{1}{m}x)^{L-i}$$第一个式子:在没有结束的串后随意添加一个字符,可能结束也可能没有结束,+1是为了补齐余项。

第二个式子:\(L\)表示\(|S|\)\(m\)是字符集,\((bool)a_i\)表示\(i\)是不是一个\(border\)。在没有结束的串后加\(S\),可能加到第\(L-i\)个字符就结束了,这个时候要求\(i\)是原串的\(border\)
这里\(border\)的含义是\(S_{1...i}=S_{n-i+1...n}\)




将第一个式子求导:$$F'(x)+G'(x)=G'(x)*x+G(x)$$故\(F'(1)=G(1)\)
\(x=1\)代入第二个式子得$$G(1)(\frac{1}{m})L=\sum_{i=1}La_iF(1)(\frac{1}{m}){L-i}$$又因为$F(1)=1$(概率和为1),所以$$F'(1)=G(1)=\sum_{i=1}a_im^i$$用KMP求每个位置上的\(Border\)就好了

代码

#include<iostream>
using namespace std;
const int N=1e5+10,mod=1e4;
int s[N],v[N],nxt[N],l,n,t;
int main()
{
    cin>>n>>t;v[0]=1;
    for(int o=1;o<=t;o++)
    {
        int l,ans=0;cin>>l;
        for(int i=1;i<=l;i++) scanf("%d",&s[i]),v[i]=v[i-1]*n%mod;
        for(int i=2;i<=l;i++)
        {
            int j=nxt[i-1];
            while(s[i]!=s[j+1]&&j) j=nxt[j];
            nxt[i]=s[i]==s[j+1]?j+1:j;
        }
        for(int p=l;p;p=nxt[p]) (ans+=v[p])%=mod;
        cout<<ans/1000%10<<ans/100%10<<ans/10%10<<ans%10<<endl;
    }
}
posted @ 2019-01-29 09:10  饕餮传奇  阅读(302)  评论(2编辑  收藏  举报