zoukankan      html  css  js  c++  java
  • [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}^{L}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}^{L}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;
        }
    }
    
  • 相关阅读:
    VS2008环境下CEGUI 0.7.1及相关工具的编译(转载 + 额外的注意事项)
    Makefile的学习
    Erlang 程序文档(转)
    erlang 二进制数据
    erlang中命令行传参,以及类型等。
    笔记:JAVA的静态变量、静态方法、静态类
    关于手机定位方案设计
    转:eclipse技巧
    DXUT CD3DArcBall类
    关于模型转向自然化思考
  • 原文地址:https://www.cnblogs.com/xzyxzy/p/10332566.html
Copyright © 2011-2022 走看看