题目描述
分析
本来以为这题很难,结果是求字符串A有多少个子串包含字符串B。
于是就可以记录字符串A中每个字符串B的开头位置,设共有
k
k
k个,然后记录包含第
i
i
i~
k
k
k个字符串B的子串个数。其中字符串匹配的部分用
K
M
P
⋅
KMP·
KMP⋅改。
复杂度
O
(
n
)
O(n)
O(n)?
#include<bits/stdc++.h>
#define ll long long
using namespace std;
char s[10010000],a[10010000],ch;
ll n,m,i,j,k,l,o,p,ans;
ll b[10010000],nxt[10010000];
int main()
{
// freopen("match.in","r",stdin);
// freopen("match.out","w",stdout);
scanf("%lld%lld",&n,&m);
scanf("%s",s);
scanf("%s",a);
j=0,k=-1;
nxt[0]=-1;
while(j<m-1)
{
if(k==-1 || a[j]==a[k])
{
j++;
k++;
nxt[j]=k;
}
else k=nxt[k];
}
k=i=j=0;
while(i<n)
{
if(j==-1 || s[i]==a[j])
{
i++;
j++;
}
else j=nxt[j];
if (j>=m) b[++k]=i-m,j=nxt[j],i=i-m+1;
}
b[0]=-1;
for (i=1;i<=k;i++)
ans+=(b[i]-b[i-1])*(n-b[i]-m+1);
printf("%lld\n",ans);
}