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;
        }
    }
    
  • 相关阅读:
    11.11 ntsysv:管理开机服务
    11.13 ethtool:查询网卡参数
    11.14 mii-tool:管理网络接口的状态
    11.15 dmidecode:查询系统硬件信息
    11.16-18 lsci、ipcs、ipcrm:清除ipc相关信息
    Devops 导论
    * SPOJ PGCD Primes in GCD Table (需要自己推线性筛函数,好题)
    SPOJ
    HDU 1695 莫比乌斯反演
    HDU 1800 hash 找出现最多次数的字符串的次数
  • 原文地址:https://www.cnblogs.com/xzyxzy/p/10332566.html
Copyright © 2011-2022 走看看