首页 > 技术文章 > poj2752 Seek the Name, Seek the Fame

yzxverygood 2018-08-19 15:51 原文

传送门

题目大意

给你一个字符串,求既是它的前缀又是它的后缀的子串个数。

分析

这个题很明显是kmp的nxt数组的应用(为了显得我很厉害不妨假装它是border的应用),因为nxt[i]表示1~i-1的最长的既是前缀又是后缀的子串的长度,所以我们用nxt数组递归求解就行了。

实际挺好理解的,自己写写画画应该不难证明这样做的正确性。

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<queue>
#include<ctime>
#include<vector>
#include<set>
#include<map>
#include<stack>
using namespace std;
char s[400100];
int nxt[400100],n;
inline void getnxt(){
      int i=0,j=-1;
      while(i<n){
          if(j==-1||s[i]==s[j])i++,j++,nxt[i]=j;
          else j=nxt[j];
      }
      return;
}
inline void solve(int x){
      if(!nxt[x])return;
      solve(nxt[x]);
      printf("%d ",nxt[x]);
      return;
}
int main(){
      while(scanf("%s",s)!=EOF){
          memset(nxt,0,sizeof(nxt));
          nxt[0]=-1;
          n=strlen(s);
          getnxt();
          solve(n);
          printf("%d\n",n);
      }
      return 0;
}

推荐阅读