#include<stdio.h> #include<string.h> #include <algorithm> #include<queue> #include<string> #include<iostream> using namespace std; const int maxn=(int)5e5+1e5; const int maxm=(int)1e6+1e5+5; #define meowmeow meow-- int pos[100005]; char s1[(int)2e5+10]; char s[maxm]; struct ac_shuaishuai { #define beg 'a' #define sz 27 int tot=0,f[maxn],nxt[maxn][sz],v[maxn],len[maxn]; void init(int k=0){ if(k==0)tot=0; memset(nxt[k],0,sizeof nxt[k]); f[k]=v[k]=len[k]=0; } int inst(const char s[]){ int i=0,now=0; while(s[i]){ int t=s[i]-beg; if(!nxt[now][t]) { nxt[now][t]=++tot; init(tot); } now=nxt[now][t]; len[now]=++i; } return now; } void bulid(){ queue<int>q; q.push(0); while(!q.empty()){ int x=q.front(); q.pop(); for(int i=0; i<sz; i++) if(nxt[x][i]) { if(nxt[x][i]!=nxt[f[x]][i]) f[nxt[x][i]]=nxt[f[x]][i]; q.push(nxt[x][i]); } else nxt[x][i]=nxt[f[x]][i]; } } int match(const char s[]){ int st=0;int wangwang; for(int i=0,j=1;s[i];i++,j++) { if(s[i]=='a'+27){j=0;continue;} if(s[i]=='a'+26) wangwang=j; st=nxt[st][s[i]-beg]; for(int k=st; k; k=f[k]) if(wangwang>=len[k]) v[k]++; } return 1; } #undef beg #undef sz }; ac_shuaishuai ac; int meow,n,m; void init(){ ac.init(); } void input(){ char c='a'+26;int beg=0,ed=0; for(int i=0;i<n;i++){ scanf("%s",s+beg); // cout<<s<<endl; while(s[ed])ed++;s[ed++]=c; while(s[beg]!=c)s[ed++]=s[beg++];s[ed++]=c+1; beg=ed;s[beg]=0; } for(int i=1;i<=m;i++){ int j=0,k=100005; scanf("%s %s",s1+k,s1); while(s1[j])j++;s1[j++]=c; while(s1[k])s1[j++]=s1[k++];s1[j]=0; pos[i]=ac.inst(s1);//记录该前后缀的结点号,这样就能处理重复查询同一个前后缀的问题了 } } int main() { #ifdef shuaishuai freopen("C:\Users\hasee\Desktop\a.txt","r",stdin); // freopen("C:\Users\hasee\Desktop\c.txt","w",stdout); #endif scanf("%d",&meow); while(meowmeow) { scanf("%d%d ",&n,&m); init(); input(); ac.bulid(); ac.match(s); for(int i=1;i<=m;i++){ printf("%d ",ac.v[pos[i]]); } } }