您的位置:首页 > 其它

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

2018-06-02 22:51 253 查看
我们定义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
,extand
;
char S
; 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\n",ans);
}
int main(){
scanf("%s",S+1);
getnext();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: