AC自动机板子

用于查找主串中有多少个模式串

int ne[maxn];//存节点u回跳边的节点 
int ch[maxn][80],cnt[maxn],idx;
void buildtrie(){
		for(int i=0;i<=idx;i++){
			for(int j=0;j<79;j++){
				ch[i][j]=0;
			}
		}
		for(int i=0;i<=idx;i++){
			cnt[i]=0;
		}
		idx=0;
}
	//ch[i][j]:记录从节点i走j的路径到达的节点编号 
void insert(string s){
		int p=0;
		for(int i=0;i<s.size();i++){
			int j=s[i]-'a';
			if(!ch[p][j]){
				ch[p][j]=++idx;
			}
			p=ch[p][j];
		}
		cnt[p]++;
}

void build(){
	queue<int>q;
	for(int i=0;i<26;i++){
		if(ch[0][i])q.push(ch[0][i]);
	}
	while(q.size()){
		int u=q.front();q.pop();
		for(int i=0;i<26;i++){
			int v=ch[u][i];
			if(v){
				ne[v]=ch[ne[u]][i];q.push(v);
			}else ch[u][i]=ch[ne[u]][i];//叶节点 
		}
	}
}

int query(string s){
	int ans=0;
	for(int k=0,i=0;s[k];k++){
		i=ch[i][s[k]-'a'];
		for(int j=i;j&&~cnt[j];j=ne[j]){
			ans+=cnt[j];cnt[j]=-1;
		}
	}
	return ans;
}

void solve(){
	int n;cin>>n;
	buildtrie();
	for(int i=1;i<=n;i++){
		string s;cin>>s;
		insert(s);
	}
	build();
	string t;cin>>t;
	cout<<query(t)<<endl;
}


a
posted @ 2025-03-16 16:34  Marinaco  阅读(10)  评论(0)    收藏  举报
//雪花飘落效果