CodeForces - 1016B Segment Occurrences
题意:
给定两个字符串 s 和 t ,有 q 次查询,每次给定 s 串的范围,求在这个范围内 t 串出现的次数(可以重叠)。
思路:
利用KMP算法
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<stack>
#include<map>
#include<algorithm>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn=1e6+10;
int n,m,q;
char s[maxn],t[maxn];
int nxt[maxn],tlen;
void getnxt()
{
int j,i = 0;
j = nxt[0] = -1;
while(i < tlen)
{
if(j==-1 || t[i]==t[j])
{
i++,j++;
if(t[i]!=t[j])
nxt[i] = j;
else
nxt[i] = nxt[j];
}
else
j = nxt[j];
}
}
int KMP(char *p,int slen)
{
int i,j;
i = j =0;
int cnt = 0;
while(i<slen && j<tlen)
{
if(j==-1 || t[j]==p[i])
i++,j++;
else
j = nxt[j];
if(j==m)
{
cnt++;
j = nxt[j];
}
}
return cnt;
}
int main()
{
int l,r;
scanf("%d%d%d",&n,&m,&q);
scanf("%s",s);
scanf("%s",t);
tlen = strlen(t);
getnxt();
for(int i=0;i<q;i++)
{
scanf("%d%d",&l,&r);
if(r-l+1 < tlen)
printf("0\n");
else
printf("%d\n",KMP(s+l-1,r-l+1));
}
return 0;
}