自己造了几组没看出问题
就是正着跑一遍kmp,然后倒过来反着跑的时候判断一下对面区间合不合法
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10,M=1e3+10;
char S[N],SS[N],s[M],ss[M];
int n,m,q,j,ans,k1[M],k2[M],t[M];
signed main(){
scanf("%s",S+1);n=strlen(S+1);
for(int i=1;i<=n;i++)SS[i]=S[n-i+1];
scanf("%d",&q);
while(q--){
scanf("%s",s+1);m=strlen(s+1);
if(m>n||m==1)continue;
memset(k1,0,sizeof(k1));memset(k2,0,sizeof(k2));memset(t,0,sizeof(t));
for(int i=2;i<=m;i++)
{while(j&&s[j+1]!=s[i])j=k1[j];if(s[j+1]==s[i])j++;k1[i]=j;}j=0;
for(int i=1;i<=n;i++){
while(j&&s[j+1]!=S[i])j=k2[j];if(s[j+1]==S[i])j++;
if(!t[j])t[j]=i;
}j=0;
for(int i=1;i<=m;i++)ss[i]=s[m-i+1];
// for(int i=1;i<=m;i++)printf("%d ",t[i]);puts("");
for(int i=2;i<=m;i++)
{while(j&&ss[j+1]!=ss[i])j=k2[j];if(ss[j+1]==ss[i])j++;k2[i]=j;}j=0;
for(int i=1;i<=n;i++){
while(j&&ss[j+1]!=SS[i])j=k2[j];if(ss[j+1]==SS[i])j++;
if(t[m-j]&&t[m-j]<n-i+1){ans++;break;}
}j=0;
}
printf("%d\n",ans);
return 0;
}