RT,从双倍经验来的,但是卡了很久卡不过去,有可能是过程中的问题,样例过了。
#include <bits/stdc++.h>
#pragma GCC optimize("Ofast,no-stack-protector")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
using namespace std;
template <typename T>inline void read(T& t){t=0; register char ch=getchar(); register int fflag=1;while(!('0'<=ch&&ch<='9')) {if(ch=='-') fflag=-1;ch=getchar();}while(('0'<=ch&&ch<='9')){t=t*10+ch-'0'; ch=getchar();} t*=fflag;}
template <typename T,typename... Args> inline void read(T& t, Args&... args) {read(t);read(args...);}
const int N=5e6, inf=0x3f3f3f3f;
struct BIT{
int val[N],n;
void intt(int _n){n=_n;}
void update(int l,int r,int va){
for(register int i=r+1;i<=n;i+=i&(-i)) val[i]-=va;
for(register int i=l;i<=n;i+=i&(-i)) val[i]+=va;
}
int Query(int u){
int res=0;
for(register int i=u;i;i-=i&(-i)) res+=val[i];
return res;
}
};
BIT seg;
int n,m,trie[N][27],cnt,Map[N],fail[N];
string st[N];
void update(string ost,int id){
int u=0;
for(int i=0;i<ost.size();++i){
if(!trie[u][ost[i]-'a']) trie[u][ost[i]-'a']=++cnt;
u=trie[u][ost[i]-'a'];
}
Map[id]=u;
}
void get_fail(){
queue<int>Q;
for(int i=0;i<26;++i) if(trie[0][i]) Q.push(trie[0][i]);
while(!Q.empty()){
int u=Q.front(); Q.pop();
for(int i=0;i<26;++i)
if(trie[u][i]){
fail[trie[u][i]]=trie[fail[u]][i];
Q.push(trie[u][i]);
}else trie[u][i]=trie[fail[u]][i];
}
} //把 fail 树建出来
int sz[N],id[N],top[N],zr[N],dep[N],fa[N],tot;
vector<int>G[N];
void dfs(int u,int F){
sz[u]=1; fa[u]=F; dep[u]=dep[F]+1;
for(int v:G[u]){
if(v==F) continue;
dfs(v,u);
sz[u]+=sz[v];
zr[u]=(zr[u]==-1||sz[v]>sz[zr[u]])?v:zr[u];
}
}
void dfs1(int u,int tp){
top[u]=tp; id[u]=++tot;
if(~zr[u]) dfs1(zr[u],tp);
for(int v:G[u]){
if(v==zr[u]||v==fa[u]) continue;
dfs1(v,v);
}
}
bool cmp(int x,int y){
return id[x]<id[y];
}
void update(int x,int y,int val){
while(top[x]!=top[y]){
if(dep[top[x]]>dep[top[y]]) swap(x,y);
seg.update(id[top[y]],id[y],val);
y=fa[top[y]];
}
if(dep[x]>dep[y]) swap(x,y);
seg.update(id[x],id[y],val);
}
int LCA(int x,int y){
while(top[x]!=top[y]){
if(dep[top[x]]>dep[top[y]]) swap(x,y);
y=fa[top[y]];
}
return (dep[x]>dep[y])?y:x;
}
int D[N];
void Query(string ost){
int u=0,pcnt=0;
for(int i=0;i<ost.size();++i){
u=trie[u][ost[i]-'a'];
D[++pcnt]=u;
}
sort(D+1,D+pcnt+1,cmp);
for(int i=1;i<=pcnt;++i) update(D[i],0,1);
for(int i=1;i<pcnt;++i) update(LCA(D[i],D[i+1]),0,-1);
}
inline void write(int x){
if(x>=10) write(x/10);
putchar(x+'0');
}
int main(){
read(n,m);
memset(zr,-1,sizeof(zr));
for(int i=1;i<=n;++i) cin>>st[i];
for(int i=1;i<=m;++i){
string pst;
cin>>pst;
update(pst,i);
}
get_fail();
for(int i=1;i<=cnt;++i) G[fail[i]].push_back(i);
dfs(0,-1); dfs1(0,0);
seg.intt(cnt+1);
for(int i=1;i<=n;++i) Query(st[i]);
for(int i=1;i<=m;++i) write(seg.Query(id[Map[i]])),putchar('\n');
return 0;
}```