51Nod - 1304 :字符串的相似度 (裸的扩展KMP)

Posted hua-dong

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了51Nod - 1304 :字符串的相似度 (裸的扩展KMP)相关的知识,希望对你有一定的参考价值。

我们定义2个字符串的相似度等于两个串的相同前缀的长度。例如 "abc" 同 "abd" 的相似度为2,"aaa" 同 "aaab" 的相似度为3。

给出一个字符串S,计算S同他所有后缀的相似度之和。例如:S = "ababaa",所有后缀为:
 
ababaa 6
babaa 0
abaa 3
baa 0
aa 1
a 1
 
S同所有后缀的相似度的和 = 6 + 0 + 3 + 0 + 1 + 1 = 11

Input输入一个字符串S(1 <= L <= 1000000),L为字符串S的长度,且S由a-z的小写字母组成。Output输出S同所有后缀的相似度的和。Sample Input

ababaa

Sample Output

11

 

 :  KMP可以求S串以i结尾的后缀与T串的前缀最长公共串长度。

 : 扩展KMP可以求S串以i为起点的的后缀与T串的前缀的最长公共字串。

   此题就是求所有i的扩展KMP长度;

以前学过,已经忘得差不多了。这里再抄一发。

 

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
const int N = 1001010;
int next[N],extand[N];
char S[N]; long long ans;
void getnext(){
     int i,length=strlen(S+1);
     next[1]=length;
     for(i=0;i+1<length&&S[i+1]==S[i+2];i++);
     next[2]=i;
     int a=2;
     for(int k=3;k<=length;k++){
          int p=a+next[a]-1, L=next[k-a+1];
          if(L>=p-k+1){
              int j=(p-k+1)>0?(p-k+1):0;
              while(k+j<=length&&S[k+j]==S[j+1]) j++;
              next[k]=j, a=k;
          } 
          else next[k]=L;
    } 
    for(int i=1;i<=length;i++) ans+=next[i];
    printf("%lld
",ans);
}
int main(){
    scanf("%s",S+1);
    getnext(); 
    return 0;
}

 

以上是关于51Nod - 1304 :字符串的相似度 (裸的扩展KMP)的主要内容,如果未能解决你的问题,请参考以下文章

51Nod1317 相似字符串对 容斥原理 动态规划

51Nod 1182 完美字符串 (贪心)

51nod贪心算法入门-----完美字符串

51 NOD 1753 相似子串 字符串hash

51NOD 1182 完美字符串

51nod1317 相似字符串对 组合数学