改了好多次了,空间不管开大或开小,不是 TLE 就是 RE ,也尝试过把队列和深搜改成数组手动模拟,都没有效果,求大佬帮助!
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#define N 50005
#define M 100005
#define maxlen (N+M)<<2
using namespace std;
int n,m,s[maxlen],cnt=1;
int namepos[N],querypos[M],d[maxlen],fail_fa[maxlen];
struct node{int ch[27],fail,fa;}t[maxlen];
int extend(int len){
int u=1;
for(int i=1;i<=len;i++){
int v=t[u].ch[s[i]];
if(!v) t[u].ch[s[i]]=++cnt;
t[t[u].ch[s[i]]].fa=u;
u=t[u].ch[s[i]];
}
return u;
}
int q[maxlen],ta,hd;
void Get_fail(){
for(int i=0;i<=26;i++) t[0].ch[i]=1;
t[1].fail=0;
hd=ta=1;
q[ta++]=1;
while(hd!=ta){
int u=q[hd];hd++;
for(int i=0;i<=26;i++){
int v=t[u].ch[i],Fail=t[u].fail;
if(!v){
t[u].ch[i]=t[Fail].ch[i];
continue;
}
t[v].fail=t[Fail].ch[i];
q[ta++]=v;
}
}
return;
}
int head[maxlen],nex[maxlen],to[maxlen],tot;
int cnt_dfn,size[maxlen],loc[maxlen];
int st[maxlen],tp;
void Get_dfn(){
st[++tp]=0;
d[0]=0;
while(tp){
int u=st[tp];
if(!head[u]){
size[fail_fa[u]]+=size[u];
tp--;
continue;
}
int v=to[head[u]];head[u]=nex[head[u]];
loc[v]=++cnt_dfn,d[v]=d[u]+1,fail_fa[v]=u,size[v]=1;
st[++tp]=v;
}
return;
}
int lca(int x,int y){
if(d[x]>d[y]) swap(x,y);
while(d[x]!=d[y]) y=fail_fa[y];
if(x==y) return x;
while(x!=y) x=fail_fa[x],y=fail_fa[y];
return x;
}
int tree[maxlen<<1];
void add(int x,int y){
if(x==0) return;
for(;x<=maxlen;x+=(x&-x)) tree[x]+=y;
return;
}
int get_sum(int x){
int res=0;
for(;x;x-=(x&-x)) res+=tree[x];
return res;
}
int sum(int l,int r){return get_sum(r)-get_sum(l);}
int rec[maxlen];
bool cmp(int x,int y){return loc[x]<loc[y];};
void solve1(){
for(int i=1;i<=n;i++){
int u=namepos[i];
int len=0;
while(u!=1){
rec[++len]=u;
add(loc[u],1);
u=t[u].fa;
}
sort(rec+1,rec+len+1,cmp);
for(int j=1;j<len;j++){
add(loc[lca(rec[j],rec[j+1])],-1);
}
}
for(int i=1;i<=m;i++){
int u=querypos[i];
cout<<sum(loc[u]-1,loc[u]+size[u]-1)<<endl;
}
return;
}
void solve2(){
for(int i=1;i<=m;i++){
int u=querypos[i];
add(loc[u],1);
add(loc[u]+size[u],-1);
}
for(int i=1;i<=n;i++){
int u=namepos[i],res=0,len=0;
while(u!=1){
rec[++len]=u;
res+=get_sum(loc[u]);
u=t[u].fa;
}
sort(rec+1,rec+len+1,cmp);
for(int j=1;j<len;j++) res-=get_sum(loc[lca(rec[j],rec[j+1])]);
cout<<res<<" ";
}
return;
}
int main(){
//freopen("data.in","r",stdin);
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
int len1,len2,num;
scanf("%d",&len1);
for(int j=1;j<=len1;j++) scanf("%d",&s[j]);
s[len1+1]=26;
scanf("%d",&len2);
for(int j=1;j<=len2;j++) scanf("%d",&s[j+len1+1]);
namepos[i]=extend(len1+len2+1);
}
for(int i=1;i<=m;i++){
int len,num;
scanf("%d",&len);
for(int i=1;i<=len;i++) scanf("%d",&s[i]);
querypos[i]=extend(len);
}
Get_fail();
for(int i=1;i<=cnt;i++){
nex[++tot]=head[t[i].fail];
head[t[i].fail]=tot;
to[tot]=i;
}
Get_dfn();
solve1();
memset(tree,0,sizeof(tree));
solve2();
return 0;
}