求助AC自动机76分TLE
查看原帖
求助AC自动机76分TLE
304524
崔化博楼主2023/1/16 16:12
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <string>
#include <queue>
#include <cstring>
#include <map>
#define N 200005
using namespace std;
struct AC{
	int tot,ch[N][26],fail[N],ed[N],val[N];
	AC(){
		tot=0;
		memset(ch,-1,sizeof(ch));
		memset(fail,0,sizeof(fail));
		memset(ed,0,sizeof(ed));
		memset(val,0,sizeof(val));
	}
	void ins(int num,string s){
		int now=0;
		for(int i=0;i<s.size();++i){
			if(ch[now][s[i]-'a']==-1)
				ch[now][s[i]-'a']=++tot;
			now=ch[now][s[i]-'a'];
		}
		ed[now]=num;
	}
	void get_fail(){
		queue<int> l;
		for(int i=0;i<26;++i){
			if(ch[0][i]!=-1){
				l.push(ch[0][i]);
			}
		}
		while(!l.empty()){
			int u=l.front();
			l.pop();
			for(int i=0;i<26;++i){
				if(ch[u][i]!=-1){
					fail[ch[u][i]]=max(ch[fail[u]][i],0);
					l.push(ch[u][i]);
				}
				else{
					ch[u][i]=ch[fail[u]][i];
				}
			}
		}
	}
	void query(string s){
		int now=0;
		for(int i=0;i<s.size();++i){
			now=ch[now][s[i]-'a'];
			if(now==-1)
				now=0;
			for(int j=now;j&&j!=-1;j=fail[j]){
				++val[ed[j]];
			}
		}
	}
}zdj;
int n,m; 
string read(){
	char c=getchar();
	while(c<'a'||c>'z')
		c=getchar();
	string s="";
	while(c>='a'&&c<='z'){
		s+=c;
		c=getchar();
	}
	return s;
}
struct node{
	string s;
	int id;
	bool operator <(const node &b)const{
		return s<b.s;
	}
}s[N];
string t;
int shang[N],ans[N];
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;++i){
		s[i].s=read();
		s[i].id=i;
	}
	sort(s+1,s+n+1);
	int lst=1;
	zdj.ins(1,s[1].s);
	for(int i=2;i<=n;++i){
		if(s[i].s==s[lst].s){
			shang[i]=lst;
		}
		else{
			zdj.ins(i,s[i].s);
			lst=i;
		}
	}	
	zdj.get_fail();
	t=read();
	zdj.query(t);
	for(int i=1;i<=n;++i){
		if(!shang[i])
			ans[s[i].id]=zdj.val[i];
		else
			ans[s[i].id]=zdj.val[shang[i]];
	}
	for(int i=1;i<=n;++i){
		printf("%d\n",ans[i]);
	}																														
	return 0;
} 
/*

*/      

可能是我处理同样的字符串的地方很复杂,有没有大佬帮我看一下

2023/1/16 16:12
加载中...