zoukankan      html  css  js  c++  java
  • 【BZOJ1152】歌唱王国(生成函数,KMP)

    【BZOJ1152】歌唱王国(生成函数,KMP)

    题面

    BZOJ
    洛谷

    题解

    根据(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))为其普通型生成函数,那么我们可以得到:

    [F(x)+G(x)=1+G(x)x ]

    这个式子什么意思呢?首先右侧的(1+G(x)x)表示在当前序列后面随机加上一个字符,要加一的愿意是(g_0=1)。那么随机加完一个字符后,结束的概率是变成了(F(x)),未结束的概率是(G(x)),所以得到了这个等式。
    (a_i)表示(A[1..i])是否是串(A)(border),那么我们可以得到:

    [G(x)(frac{1}{m})^Lx^L=sum_{i=1}^{L}a_iF(x)(frac{1}{m})^{L-i}x^{L-i} ]

    等式左侧的含义是在当前未结束的串的后面直接接上目标串,那么这样一定会结束。
    右侧的含义是因为前面的随机串中可能已经匹配了一部分的长度,导致在匹配了一半此时就已经结束了。
    那么我们插入了一半就结束了,并且此时我们插入的一定是一段前缀,因此只有可能当这个位置是(border)时才可能结束。
    那么强制在这个(border)时会结束,等价于我们钦定了随机串的最后(L-i)位。那么就得到了右边的式子。
    我们要求解的东西是(F'(1))
    首先第一个式子可以写成:

    [F'(x)+G'(x)=G(x)+G'(x)x ]

    化简得到(F'(1)=G(1))
    然后令(x=1)带入到第二个式子中,可以得到:

    [G(1)=sum_{i=1}^La_im^i ]

    那么只需要(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;
    }
    
  • 相关阅读:
    stm32 IO模式
    stm32的ADC
    bsp
    stm32的硬件调试设置
    RTC实时时钟
    快手2019笔试题 “回文子串" 解题思路
    C++内存修改器开源代码
    FC游戏修改教程(hack)小白文。
    GLFW+GLEW搭建opengl环境(备忘)
    8086 IO读写操作
  • 原文地址:https://www.cnblogs.com/cjyyb/p/10649150.html
Copyright © 2011-2022 走看看