KMP
char a[N],b[N];
int nxt[N];
int n,m;
void Cal_nxt()
{
int i;
nxt[0]=-1;
for(i=1;i<m;i++)
{
int j=nxt[i-1];
while(j>=0&&b[i]!=b[j+1]) j=nxt[j];
nxt[i]=b[i]==b[j+1]?j+1:-1;
}
}
int Kmp()
{
int i,j=0;
for(i=0;i<n&&j<m;i++)
{
while(j>0&&a[i]!=b[j]) j=nxt[j-1]+1;
if(a[i]==b[j]) j++;
}
return (j==m)?(i-m):-1;
}
拓展KMP
const int M=100010;
const int N=100010;
char a[N],b[M];
int nxt[M],ex[N];
int n,m;
void Cal_nxt()
{
int i=0;
nxt[0]=m;
while(b[0]==b[i+1]&&i+1<m) i++;
nxt[1]=i;
int po=1;
for(i=2;i<m;i++)
{
if(nxt[i-po]+i<nxt[po]+po) nxt[i]=nxt[i-po];
else
{
int j=nxt[po]+po-i;
if(j<0) j=0;
while(i+j<m&&b[j]==b[j+i]) j++;
nxt[i]=j;
po=i;
}
}
}
void Exkmp()
{
int i=0;
cal_nxt();
while(a[i]==b[i]&&i<n&&i<m) i++;
ex[0]=i;
int po=0;
for(i=1;i<n;i++)
{
if(nxt[i-po]+i<ex[po]+po) ex[i]=nxt[i-po];
else
{
int j=ex[po]+po-i;
if(j<0) j=0;
while(i+j<n&&j<m&&a[j+i]==b[j]) j++;
ex[i]=j;
po=i;
}
}
}