传送门:ZOJ3643
很有意思的KMP。
kmp就不说啥了。
这道题的瓶颈在于暴力删除会超时,于是我们观察注意到[l,r]被删除之后,造成的影响仅仅是下一次我们会从l-1开始匹配。
然后就可以乱搞了……
栈里面存的是母串在子串中匹配到的位置。
代码上的小细节见下。
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <stack>
using namespace std;
stack<int> Q;
int ans;
int pre[1000005];
char P[1000005];
char T[1000005];
void Make_Table(char* S,int* pre)
{
int len=strlen(S+1);
pre[1]=0;int k=0;
for(int i=2;i<=len;i++){
while(k&&S[k+1]!=S[i])
k=pre[k];
if(S[k+1]==S[i])
k++;
pre[i]=k;
}
}
void GetAns(char* P,char* T)
{
Q.push(0);int j=0,len1=strlen(P+1),len2=strlen(T+1);
ans=0;
for(int i=1;i<=len1;i++){
while(j&&T[j+1]!=P[i])
j=pre[j];
if(T[j+1]==P[i])
j++;
Q.push(j);
if(j==len2){
ans++;
for(int i=1;i<=len2;i++)
Q.pop();
j=Q.empty()?0:Q.top();
}
}
printf("%d\n",ans);
}
void Solve()
{
freopen("loli.in","r",stdin);
while(~scanf("%s%s",T+1,P+1)){
Make_Table(T,pre);
GetAns(P,T);
}
}
void Close()
{
fclose(stdin);
fclose(stdout);
}
int main()
{
Solve();
Close();
return 0;
}