P2336 AC自动机 求助 RE
  • 板块学术版
  • 楼主Adelaide_Black
  • 当前回复0
  • 已保存回复0
  • 发布时间2024/4/17 09:59
  • 上次更新2024/4/17 15:54:04
查看原帖
P2336 AC自动机 求助 RE
450334
Adelaide_Black楼主2024/4/17 09:59

题目链接

改了好多次了,空间不管开大或开小,不是 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;
}
2024/4/17 09:59
加载中...