题目:给出若干模板串和一个母串,求每个模板串在母串中出现的次数.
思路:AC自动机+后缀链接(last数组)
/* * @author: Cwind */ ///#pragma comment(linker, "/STACK:102400000,102400000") #include <iostream> #include <map> #include <algorithm> #include <cstdio> #include <cstring> #include <cstdlib> #include <vector> #include <queue> #include <stack> #include <functional> #include <set> #include <cmath> using namespace std; #define IOS std::ios::sync_with_stdio (false);std::cin.tie(0) #define pb push_back #define PB pop_back #define bk back() #define fs first #define se second #define sq(x) (x)*(x) #define eps (3e-7) #define IINF (1<<29) #define LINF (1ll<<59) #define INF (1000000000) #define FINF (1e3) #define clr(x) memset((x),0,sizeof (x)); typedef long long ll; typedef unsigned long long ull; typedef pair<int,int> pii; typedef pair<int,int> P; const int maxv=1e5+3000; const int csize=26; int ch[maxv*4][csize]; int sz; bool term[maxv*4]; vector<int> termlist[maxv*4]; void Tclear(){ sz=1; clr(ch[0]);clr(term); } int last[maxv*4]; void insert(char *s,int id){ int u=0,n=strlen(s); for(int i=0;i<n;i++){ int c=s[i]-'a'; if(!ch[u][c]){ memset(ch[sz],0,sizeof ch[sz]); termlist[sz].clear(); term[sz]=0; ch[u][c]=sz++; } u=ch[u][c]; } term[u]=1; termlist[u].pb(id); } int f[maxv*4]; queue<int> Q; void getFail(){ f[0]=0; for(int c=0;c<csize;c++){ int u=ch[0][c]; if(u){ f[u]=0; Q.push(u); } } while(!Q.empty()){ int r=Q.front();Q.pop(); for(int c=0;c<csize;c++){ int u=ch[r][c]; if(!u) continue; Q.push(u); int v=f[r]; while(v&&!ch[v][c]){ v=f[v]; } f[u]=ch[v][c]; last[u]=term[f[u]]?f[u]:last[f[u]]; } } } const int maxlen=1e6+3000; const int maxn=600; int T,n; char r[maxlen]; char M[maxlen]; int ans[maxn]; int cas=0; int main(){ freopen("/home/slyfc/CppFiles/in","r",stdin); //freopen("defense.in","r",stdin); //freopen("defense.out","w",stdout); cin>>T; while(T--){ cin>>n; printf("Case %d:\n",++cas); clr(ans);clr(last); Tclear(); scanf("%s",M); for(int i=0;i<n;i++){ scanf("%s",r); insert(r,i+1); } getFail(); int len=strlen(M); int v=0; for(int i=0;i<len;i++){ int c=M[i]-'a'; while(v&&!ch[v][c]) v=f[v]; v=ch[v][c]; int vv=v; while(vv!=0){ for(int j=0;j<termlist[vv].size();j++){ ans[termlist[vv][j]]++; } vv=last[vv]; } } for(int i=1;i<=n;i++) printf("%d\n",ans[i]); } return 0; }