题目链接:http://poj.org/problem?id=2752
思路:我当成exkmp模板做的,别的做法应该也行,这题和符合exkmp next数组的定义
定义母串S,和字串T,设S的长度为n,T的长度为m,求T与S的每一个后缀的最长公共前缀,也就是说,设extend数组,extend[i]表示T与S[i,n-1]的最长公共前缀,要求出所有extend[i](0<=i<n)。
next[i]表示T[i,m-1]和T的最长公共前缀长度。
#include <cstdio>
#include <cstdlib>
#include <cassert>
#include <cstring>
#include <bitset>
#include <cmath>
#include <cctype>
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <sstream>
#include <iomanip>
using namespace std;
typedef long long ll;
typedef vector<long long> VI;
typedef unsigned long long ull;
const ll inff = 0x3f3f3f3f3f3f3f3f;
#define FOR(i,a,b) for(int i(a);i<=(b);++i)
#define FOL(i,a,b) for(int i(a);i>=(b);--i)
#define SZ(x) ((long long)(x).size())
#define REW(a,b) memset(a,b,sizeof(a))
#define inf int(0x3f3f3f3f)
#define si(a) scanf("%d",&a)
#define sl(a) scanf("%lld",&a)
#define sd(a) scanf("%lf",&a)
#define ss(a) scanf("%s",a)
#define mod ll(1e9+7)
#define pb push_back
#define eps 1e-6
#define lc d<<1
#define rc d<<1|1
#define Pll pair<ll,ll>
#define P pair<int,int>
#define pi acos(-1)
int n;
const int maxn=400010; //字符串长度最大值
int ne[maxn],ex[maxn]; //ex数组即为extend数组
char a[maxn];
//预处理计算next数组
void gne(char *str)
{
int i=0,j,po,len=strlen(str);
ne[0]=len;//初始化next[0]
while(str[i]==str[i+1]&&i+1<len) i++;//计算next[1]
ne[1]=i;po=1;//初始化po的位置
for(i=2;i<len;i++)
{
if(ne[i-po]+i<ne[po]+po) ne[i]=ne[i-po];//第一种情况,可以直接得到next[i]的值
else//第二种情况,要继续匹配才能得到next[i]的值
{
j=ne[po]+po-i;
if(j<0) j=0;//如果i>po+next[po],则要从头开始匹配
while(i+j<len&&str[j]==str[j+i]) j++;//计算next[i]
ne[i]=j;po=i;//更新po的位置
}
}
}
//计算extend数组
void exkmp(char *s1,char *s2)
{
int i=0,j,po,len=strlen(s1),l2=strlen(s2);
gne(s2);//计算子串的next数组
while(s1[i]==s2[i]&&i<l2&&i<len) i++;//计算ex[0]
ex[0]=i;po=0;//初始化po的位置
for(i=1;i<len;i++)
{
if(ne[i-po]+i<ex[po]+po) ex[i]=ne[i-po];//第一种情况,直接可以得到ex[i]的值
else//第二种情况,要继续匹配才能得到ex[i]的值
{
j=ex[po]+po-i;
if(j<0)j=0;//如果i>ex[po]+po则要从头开始匹配
while(i+j<len&&j<l2&&s1[j+i]==s2[j]) j++;//计算ex[i]
ex[i]=j;po=i;//更新po的位置
}
}
}
int main()
{
cin.tie(0);
cout.tie(0);
while(ss(a)!=EOF)
{
gne(a);int l=strlen(a);
FOL(i,l-1,0)
if(ne[i]==l-i) printf("%d ",l-i);
puts("");
}
return 0;
}