【JZOJ4624】字符串匹配
Description
Solution
诶,这题不是赤裸裸kmp吗?
对于 |S|<|T| 的情况,直接做kmp,统计答案就行。
那对于普遍情况呢?
我们先复制
T
串使得
Code
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#define fo(i,j,k) for(int i=j;i<=k;i++)
#define fd(i,j,k) for(int i=j;i>=k;i--)
#define N 100001
#define ll long long
using namespace std;
int f[N];
char s[N],T[N*4];
int l1,l2,l3;
void get()
{
int j=0;
fo(i,2,strlen(s+1))
{
while(j>0 && s[j+1]!=s[i]) j=f[j];
if (s[j+1]==s[i]) j++;
f[i]=j;
}
}
int kmp(int l,int r)
{
int j=0;
int ans=0;
fo(i,l,r)
{
while (j>0 && s[j+1]!=T[i]) j=f[j];
if (s[j+1]==T[i]) j++;
if (j==l1)
{
ans++;
j=f[j];
}
}
return ans;
}
int main()
{
freopen("4624.in","r",stdin);
freopen("4624.out","w",stdout);
ll n;
cin>>n;
cin>>s+1;
cin>>T+1;
get();
l1=strlen(s+1),l2=strlen(T+1),l3=l2;
n--;
while(l3<=l1 && n)
{
n--;
fo(i,l3+1,l2+l3) T[i]=T[i-l2];
l3+=l2;
}
int t1=kmp(1,l3);
fo(i,l3+1,l3+l2) T[i]=T[i-l3];
l3+=l2;
int t2=kmp(1,l3);
cout<<t1*1ll+(t2-t1)*1ll*n;
}