拓展kmp
int Next[MAXN], extand[MAXN];
char s[MAXN];
void getNext(char *T)
{// Next[i]: 以第i位置开始的子串 与 T的公共前缀
int i, length = strlen(T);
Next[0] = length;
for(i = 0; i < length - 1 && T[i] == T[i+1]; i++);
Next[1] = i;
int a = 1;
for(int k = 2; k < length; k++)
{
int p = a+Next[a]-1, L = Next[k-a];
if((k - 1) + L >= p )
{
int j = (p - k + 1) > 0 ? (p - k + 1) : 0;
while(k + j < length && T[k + j] == T[j])
j++;// 枚举(p+1,length) 与(p-k+1,length) 区间比较
Next[k] = j, a = k;
}
else
Next[k] = L;
}
}
void getextand(char *S,char *T)
{
memset(Next,0,sizeof(Next));
getNext(T);
int Slen = strlen(S), Tlen = strlen(T), a = 0;
int MinLen = Slen > Tlen ? Tlen : Slen;
while(a < MinLen && S[a] == T[a]) a++;
extand[0] = a, a = 0;
for(int k = 1; k < Slen; k++)
{
int p = a + extand[a] - 1, L = Next[k-a];
if((k - 1) + L >= p )
{
int j = (p - k + 1) > 0 ? (p - k + 1) : 0;
while(k + j < Slen && j < Tlen && S[k + j] == T[j]) j++;
extand[k] = j; a = k;
}
else extand[k] = L;
}
}
KMP
#include <iostream>
using namespace std;
typedef long long ll;
const int MAXN = 1e5 + 10;
string a, text;
ll pre[100010] = {-1};
void prefix_table(string mode)
{
for(int i = 1, j = 0; i < mode.length(); i++)
{
if(mode[i] == mode[j])
{
pre[i + 1] = pre[i] + 1;
j++;
}
else //若匹配不上再次匹配时从零开始
{
j = 0;
if(mode[i] == mode[j]) //从零的第一个单独判断一
{
pre[i + 1] = 1;
j++;
}
}
}
}
int judge(int beg, int end,int lenm) //向后跳转匹配
{
int i = beg - 1, j = 0, ans = 0;
while(i < end)
{
if(j == lenm - 1 && text[i] == a[j])
{
ans++;
}
if(text[i] == a[j])
{
i++;
j++;
}
else
{
j = pre[j];
if(j==-1)
{
i++;
j++;
}
}
}
return ans;
}
int main()
{
int lent, lenm, t;
cin>>lent>>lenm>>t;
cin>>text>>a;
prefix_table(a);
while(t--)
{
int beg, end;
cin>>beg>>end;
cout<<judge(beg, end, lenm)<<endl;
}
return 0;
}