【题解】歌唱王国(概率生成函数+KMP)+伦讲的求方差

【题解】歌唱王国(概率生成函数+KMP)+伦讲的求方差

生成函数的本质是什么呀!为什么和It-st一样神

\(f_i\)表示填了\(i\)个时候停下来的概率,\(g_i\)是填了\(i\)个的时候不停下的来的概率,规定\(f_0=g_0=1\)

两个生成函数是
\[ G(x)=\sum g(i)x^i \\ F(x)=\sum f(i)x^i \]

可以得到一些关系:

  • 在后面随意加上一个字符
    \[ xG(x)+1=F(x)+G(x) \]

  • 直接强行接上原串:
    \[ x^LG(x)(\dfrac 1 {\sigma})^L \]
    此时他一定会停止,但是停止的概率是多大呢?

    可以发现,假如这个字符串没有BORDER(不存在前缀可以等于等长的后缀),\(F(x)\)\(G(x)\)是独立的,但是有BORDER的时候怎么办呢?

    由于\(f_i\)代表在填出来的字符串第\(i\)位时停下的概率,所以此时填出来的字符串尾巴的情况是确定的,由于存在BORDER,我们就不用直接强行接上\(L\)那么长的串,可能到一半就填出来了,不难发现就是
    \[ x^LG(x)(\dfrac 1 {\sigma})^L=\sum [i\in B](\dfrac 1 {\sigma})^{L-i}x^{L-i}F(x) \]

有了这些关系怎么办呢?我们知道,\(E(X)=\sum i\times P(X=i)\)

所以对\(F(x)\)求导,指数都到系数里面来了,所以代入\(x=1\)就得到了\(E(X)\)

答案就是\((F(1))'\)

我们之前有一些等量关系,所以
\[ F(x)'+G(x)'=(xG(x)+1'=xG(x)'+G(x) \]
所以
\[ F(1)'=G(1) \]
代入第二个式子
\[ G(1)=\sum[i \in B]\sigma^iF(1) \]
显然有概率的规范性\(F(1)=1\)

所以答案就是
\[ G(1)=\sum[i \in B]\sigma^i \]
用KMP求BORDER就是的

//@winlere
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>


using namespace std;  typedef long long ll;
inline int qr(){
      register int ret=0,f=0;
      register char c=getchar();
      while(c<48||c>57)f|=c==45,c=getchar();
      while(c>=48&&c<=57) ret=ret*10+c-48,c=getchar();
      return ret;
}

const int maxn=2e5+5;
const int mod=10000;
int data[maxn],p[maxn],fac[maxn];
int n,m;

inline int ksm(const int&base ,const int&p){
      register int ret=1;
      for(register int t=p,b=base%mod;t;t>>=1,b=b*b%mod)
        if(t&1) ret=1ll*ret*b%mod;
      return ret;
}

inline void getborder(){
      memset(p,0,sizeof p);
      for(register int t=2,k;t<=n;++t){
        k=p[t-1];
        while(k&&data[k+1]!=data[t]) k=p[k];
        if(data[k+1]==data[t])++k;
        p[t]=k;
      }
}

int main(){
#ifndef ONLINE_JUDGE
      freopen("in.in","r",stdin);
      //freopen("out.out","w",stdout);
#endif
      m=qr();
      fac[0]=1;
      for(register int t=1;t<=200000;++t) fac[t]=1ll*fac[t-1]*m%mod;
      int T=qr();
      while(T--){
        n=qr();
        for(register int t=1;t<=n;++t) data[t]=qr();  
        getborder();  
        int ans=0;  
        for(register int t=n;t;t=p[t])
          ans=(ans+fac[t])%mod;
        printf("%04d\n",ans);  
      }
      return 0;
}

如何算方差,咕咕咕先。

转载于:https://www.cnblogs.com/winlere/p/11253146.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值