解题:CTSC 2006 歌唱王国

题面

概率生成函数

对于菜鸡博主来说好难啊

其一般形式为$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
 2 #include
 3 #include
 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) 
17             scanf("%d",&num[i]);
18         for(int i=1,o=0;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

 

转载于:https://www.cnblogs.com/ydnhaha/p/10432945.html

你可能感兴趣的:(解题:CTSC 2006 歌唱王国)