解題:CTSC 2006 歌唱王國
阿新 • • 發佈:2019-02-25
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 constView Codeint 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 }
解題:CTSC 2006 歌唱王國