1. 程式人生 > >解題:CTSC 2006 歌唱王國

解題:CTSC 2006 歌唱王國

inf pen ext src 圖片 amp ati cor 生成函數

題面

概率生成函數

對於菜雞博主來說好難啊

其一般形式為$F(x)=\sum\limits_{i=0}^∞[x==i]x_i$,第i項的系數表示離散變量x取值為i的概率

一般的兩個性質:$F(1)=1,E(x)=F‘(1)$

這裏用$F(x)$表示結束時的串長的概率生成函數,$G(x)$表示到長度到達...而串未結束的概率生成函數,字符串長為len,那麽有:

①$F(x)+G(x)=x*G(x)+1$,含義是長度達到x的概率:左邊就是字面意思,右邊$x*G(x)$表示x-1時未結束的概率,然後加上放的一次

②$\frac{1}{m}^len*G(x)=\sum\limits_{i=1}^{len} isb[i]*\frac{1}{m}^{len-i}*F(x)$,其中$isb_i$表示i是否是一個border,整個式子含義是字符串的結束:左邊就是在一個沒結束的串左邊恰好補上所需要的len個字母,右邊表示可能正好補了一個border,然後就也結束了

然後開始倒騰這兩個式子,我們的目標是搗騰出$F‘(1)$,也就是$E(x)$,而直接對①求導就可以得到$F‘(x)$與$G(x)$的關系:

$F‘(x)-G‘(x)=G‘(x)*x+G(x)$

$F‘(1)=G(1)$

然後直接把$F(1)=1$扔進第二個式子裏

$G(1)=\sum\limits_{i=0}^n isb_i m^i$

就是這樣技術分享圖片

技術分享圖片
 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 const
int N=100005,mod=10000; 6 int T,p,n,pos,ans,num[N],nxt[N],pw[N]; 7 int main() 8 { 9 scanf("%d",&p),pw[0]=1; 10 for(int i=1;i<=100000;i++) 11 pw[i]=pw[i-1]*p%mod; 12 scanf("%d",&T); 13 while(T--) 14 { 15 scanf("%d",&n); 16 for(int i=0;i<n;i++)
17 scanf("%d",&num[i]); 18 for(int i=1,o=0;i<n;i++) 19 { 20 while(o&&num[o]!=num[i]) o=nxt[o]; 21 nxt[i+1]=(num[o]==num[i])?++o:0; 22 } 23 pos=n,ans=0; 24 while(pos) ans=(ans+pw[pos])%mod,pos=nxt[pos]; 25 printf("%04d\n",ans); 26 } 27 return 0; 28 }
View Code

解題:CTSC 2006 歌唱王國