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)的主要内容,如果未能解决你的问题,请参考以下文章