zoukankan      html  css  js  c++  java
  • LG2375/LOJ2246 「NOI2014」动物园 KMP改造

    问题描述

    LG2375

    LOJ2246


    题解

    看了题解,需要回看,需要继续通过本题深入理解KMP。

    为了将 (mathrm{KMP}) 和只插入了一个模式串的(mathrm{AC})自动机有机统一,称通常意义下的 (mathrm{KMP})(mathrm{next}) 数组为 (mathrm{fail})

    通过对 (mathrm{num}) 数组的观察,发现, (mathrm{num}) 数组就是对于每一个前缀,求其公共不重叠前后缀的个数

    由于只有一个串,通过 (L le 10^6) 的线性复杂度的数据规模,可以猜出肯定和 (mathrm{KMP}) 有关。

    回顾 (mathrm{KMP})(mathrm{fail}) 数组的定义,是对于每一个前缀,其 最长公共前后缀的长度

    对于一个前缀 (i)(fail[i]) 是它的一个公共前后缀,那么 (fail[fail[i]]) 也是它的公共前后缀。

    可以画图来理解一下:

    同理, (fail[fail[fail[i]]]) ... 都是前缀 (i) 的公共前后缀。

    于是通过这个办法递推一下前缀 (i)公共前后缀数目(允许重叠),这实际上就是 (mathrm{num}) 数组的弱化版,即允许重叠的版本。

    实际上,我们求出的这个弱化版数组,就是比实际上的 (num) 数组长了一点,所以做第二次 (mathrm{KMP}) 的时候,只需要再让 (j)(mathrm{fail}) ,直到它的一半比 (i) 小。

    为什么是一半?显然 (num_i le frac{i}{2})


    (mathrm{Code})

    #include<bits/stdc++.h>
    using namespace std;
    
    template <typename Tp>
    void read(Tp &x){
    	x=0;char ch=1;int fh;
    	while(ch!='-'&&(ch>'9'||ch<'0')) ch=getchar();
    	if(ch=='-') ch=getchar(),fh=-1;
    	else fh=1;
    	while(ch>='0'&&ch<='9') x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
    	x*=fh;
    }
    
    const int maxn=1000000+7;
    const int mod=1000000007;
    
    int T,n;
    char s[maxn];
    
    int fail[maxn],num[maxn];
    
    void Reset(){
    	memset(fail,0,sizeof(fail));
    }
    
    void KMP(){
    	num[1]=1;
    	for(int i=2,j=0;i<=n;i++){
    		while(j&&s[j+1]!=s[i]) j=fail[j];
    		if(s[j+1]==s[i]) ++j;
    		fail[i]=j;num[i]=num[j]+1;
    	}
    }
    
    void solve(){
    	KMP();
    	long long ans=1;
    	for(int i=2,j=0;i<=n;i++){
    		while(j&&s[i]!=s[j+1]) j=fail[j];
    		if(s[i]==s[j+1]) ++j;
    		while((j<<1)>i) j=fail[j];
    		ans=ans*(((long long)num[j]+1ll)%mod)%mod;
    	}
    	printf("%lld
    ",ans);
    }
    
    int main(){
    	read(T);
    	while(T--){
    		scanf("%s",s+1);n=strlen(s+1);
    		solve();
    	}
    	return 0;
    }
    
  • 相关阅读:
    [bzoj3172] [Tjoi2013]单词
    [luogu2664] 树上游戏
    [bzoj3307] 雨天的尾巴
    [bzoj3141] [HNOI2013]旅行
    [bzoj4515] [SDOI2016]游戏
    [bzoj3165] [HEOI2013]Segment
    Spring MVC-从零开始-view-直接返回页面不传data
    Spring MVC-从零开始-view-ViewResolver
    Spring MVC-从零开始-@RequestMapping结合@PathVariable (从URL路径中取值,作用于函数参数)
    Spring MVC-从零开始-@RequestMapping 注解headers 属性
  • 原文地址:https://www.cnblogs.com/liubainian/p/11632350.html
Copyright © 2011-2022 走看看