想刷下AC自动机的题,搜出来个这个
但是用KMP过了..
题目链接:https://codeforces.com/contest/149/problem/E
题目大意:
给出一个t串,和m个s串,对于每个s串判断是否可以在t串中找出两个子串
使得T[a,b] + T[c,d] = s
输出所有可以的s串的个数
题目思路:
Thinking_1
嗯...稍后会更新AC自动机的写法
考虑kmp,pre_i代表s串前缀与t串前i个前缀匹配的最大长度
预处理好pre数组之后
将s串翻转,处理s串后缀与t串后i个匹配的长度,然后与pre[i-1]相加看是否已经大于等于s串的长度
注意一些细节问题,必须要分成两个那么就不可以单独一个
注意一些特判即可
Code_1
/*** keep hungry and calm CoolGuang!***/
#pragma GCC optimize(2)
//#include <bits/stdc++.h>
#include<stdio.h>
#include<string.h>
#include<queue>
#include<iostream>
#include<algorithm>
#define debug(x) cout<<#x<<":"<<x<<endl;
#define _CRT_SECURE_NO_WARNINGS
#pragma GCC optimize("Ofast","unroll-loops","omit-frame-pointer","inline")
#pragma GCC option("arch=native","tune=native","no-zero-upper")
#pragma GCC target("avx2")
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pp;
const ll INF=1e17;
const int Maxn=2e7+10;
const int maxn =1e6+10;
const int mod=1e9+7;
const int Mod = 1e9+7;
///const double eps=1e-10;
inline bool read(ll &num)
{char in;bool IsN=false;
in=getchar();if(in==EOF) return false;while(in!='-'&&(in<'0'||in>'9')) in=getchar();if(in=='-'){ IsN=true;num=0;}else num=in-'0';while(in=getchar(),in>='0'&&in<='9'){num*=10,num+=in-'0';}if(IsN) num=-num;return true;}
ll n,m,p;
int nxt[maxn];
int getnext(string p){
int len = p.size();
nxt[0] = -1;
for(int i=0,j=-1;i<len;i++){
while(~j&&p[i+1] != p[j+1]) j = nxt[j];
if(p[i+1] == p[j+1]) j++;
nxt[i+1] = j;
}
}
int pre[maxn];///前缀匹配的最大长度
int kmp(string s,string t){
pre[0] = -1;
int slen = s.size(),tlen = t.size();
getnext(s);
for(int i=0,j=-1;i<tlen;i++){
while(~j&&t[i]!=s[j+1]){
j = nxt[j];
}
if(t[i] == s[j+1]) j++;
if(i) pre[i] = max(pre[i-1],j);
else pre[i] = j;
}
reverse(s.begin(),s.end());
getnext(s);
for(int i=tlen-1,j =-1;i>0;i--){
while(~j&&t[i] != s[j+1]) j=nxt[j];
if(t[i] == s[j+1]) j++;
if(pre[i-1]>-1&&j+pre[i-1]+2>=slen) return 1;
}
return 0;
}
string s,t;
int main(){
cin>>t;
read(n);
int ans = 0;
for(int i=1;i<=n;i++){
cin>>s;
if(s.size()>1)
ans += kmp(s,t);
}
printf("%d\n",ans);
return 0;
}
/**
4
2
abcd
cdab
abcdab
ababab
**/