【BZOJ1152】歌唱王国(生成函数,KMP)
题面
题解
根据(YMD)论文来的QwQ。
首先大家都知道普通型生成函数是(displaystyle sum_{i=0}^{infty}a_ix^i),类似的定义概率生成函数(displaystyle F(x)=sum_{i=0}^infty P(X=i)x^i)。其中(P(X=i))表示(X)这个随机变量为(i)的概率。
那么我们可以知道几个结论:(displaystyle F(1)=sum_{i=0}^infty P(X=i)=1),这个结论很显然。
如果我们要求解期望,显然期望等于(displaystyle sum_{i=0}^{infty}iP(X=i))。
我们发现(displaystyle F'(x)=sum_{i=1}^infty iP(X=i)x^{i-1}),那么我们要求解的期望就是(F'(1))。
回到题目。
我们设(f_i)表示终止长度为(i)的概率,(F(x))为其概率生成函数,那么要求解的就是(F'(1))。
设(g_i)表示当前长度为(i)且还未结束的概率,(G(x))为其普通型生成函数,那么我们可以得到:
这个式子什么意思呢?首先右侧的(1+G(x)x)表示在当前序列后面随机加上一个字符,要加一的愿意是(g_0=1)。那么随机加完一个字符后,结束的概率是变成了(F(x)),未结束的概率是(G(x)),所以得到了这个等式。
设(a_i)表示(A[1..i])是否是串(A)的(border),那么我们可以得到:
等式左侧的含义是在当前未结束的串的后面直接接上目标串,那么这样一定会结束。
右侧的含义是因为前面的随机串中可能已经匹配了一部分的长度,导致在匹配了一半此时就已经结束了。
那么我们插入了一半就结束了,并且此时我们插入的一定是一段前缀,因此只有可能当这个位置是(border)时才可能结束。
那么强制在这个(border)时会结束,等价于我们钦定了随机串的最后(L-i)位。那么就得到了右边的式子。
我们要求解的东西是(F'(1)),
首先第一个式子可以写成:
化简得到(F'(1)=G(1))
然后令(x=1)带入到第二个式子中,可以得到:
那么只需要(KMP)求解(border)就行了。
#include<iostream>
#include<cstdio>
using namespace std;
#define MOD 10000
#define MAX 100100
inline int read()
{
int x=0;bool t=false;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=true,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return t?-x:x;
}
int n,T,pw[MAX],s[MAX],nt[MAX];
int main()
{
n=read();T=read();
pw[0]=1;for(int i=1;i<MAX;++i)pw[i]=1ll*pw[i-1]*n%MOD;
while(T--)
{
int m=read(),ans=0;
for(int i=1;i<=m;++i)s[i]=read();
for(int i=2;i<=m;++i)
{
int t=nt[i-1];
while(t&&s[t+1]!=s[i])t=nt[t];
if(s[t+1]==s[i])++t;
nt[i]=t;
}
for(int i=m;i;i=nt[i])ans=(ans+pw[i])%MOD;
printf("%04d
",ans);
}
return 0;
}