• Luogu4548 歌唱王国


    Luogu4548 歌唱王国

    题面:Luogu

    解析

    很有趣的一道题目。

    考虑一类生成函数,对于一个离散的整型随机变量(t),该函数的每一项(x^i)的系数表示该变量取值为(i)的概率,也就是:

    [f(x)=sum_{i=0}^{infty} P(t=i)x^i ]

    这个函数有一些有趣的性质,例如:(f(1)=1)
    以及对于(t)的期望有:(E(t)=f'(1))

    现在对于这道题目,令(n)表示字符集大小,(m)表示名字长度。

    考虑设(F(x))表示对于在唱第(i)个数字结束的概率的生成函数,(G(x))表示对于在唱第(i)个数字未结束的概率的生成函数。

    显然有下面这个式子:

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

    即在未结束的串后再接上一个字符,有可能结束,也可能不结束。

    其次,有:

    [G(x) Big(frac{1}{n}xBig)^m=sum_{i=1}^{m}a_{i}F(x)Big(frac{1}{n}xBig)^{m-i} ]

    即在未结束的串后接上名字一定会结束,但在这之前可能会提前结束,其中(a_{i}=0/1),表示(s[1,i])是否为串(s)(border)

    对第一个式子求导并化简,有:

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

    在第二个式子中带入(x=1),有:

    [G(1)=sum_{i=1}^{m} a_{i} n^{i} ]

    所以:

    [E(x)=F'(1)=G(1)=sum_{i=1}^m a_{i} n^{i} ]

    对于(a_{i})(kmp)求即可。

    代码

    
    #include<cstdio>
    #define N 100005
    
    using namespace std;
    
    inline int In(){
    	char c=getchar(); int x=0,ft=1;
    	for(;c<'0'||c>'9';c=getchar()) if(c=='-') ft=-1;
    	for(;c>='0'&&c<='9';c=getchar()) x=x*10+c-'0';
    	return x*ft;
    }
    
    const int P=10000;
    int n,T,m,s[N],nex[N],pw[N];
    
    int main(){
    	n=In(); T=In();
    	while(T--){
    		m=In(); for(int i=1;i<=m;++i) s[i]=In();
    		pw[0]=1; for(int i=1;i<=m;++i) pw[i]=pw[i-1]*n%P;
    		for(int i=2,j=0;i<=m;++i){
    			while(j&&s[j+1]!=s[i]) j=nex[j];
    			if(s[j+1]==s[i]) ++j; nex[i]=j;
    		}
    		int sum=0;
    		for(int i=m;i;i=nex[i]) sum=(sum+pw[i])%P;
    		printf("%.4d
    ",sum);
    	}
    	return 0;
    }
    
    
  • 相关阅读:
    Arduino学习笔记10
    Arduino学习笔记07
    Arduino学习笔记6
    Arduino学习笔记5
    Arduino学习笔记4
    Arduino学习笔记3
    linux下库文件的编程
    学习编程语言究竟学什么
    Arduino学习笔记2---数字温度计
    Arduino学习笔记0---开发板的了解
  • 原文地址:https://www.cnblogs.com/pkh68/p/11404703.html
Copyright © 2020-2023  润新知