码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2018-06-02 23:18:38      阅读:207      评论:0      收藏:0      [点我收藏+]

标签:inpu   turn   scanf   std   \n   print   aaa   ons   har   

我们定义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\n",ans);
}
int main(){
    scanf("%s",S+1);
    getnext(); 
    return 0;
}

 

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

标签:inpu   turn   scanf   std   \n   print   aaa   ons   har   

原文地址:https://www.cnblogs.com/hua-dong/p/9127146.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!