求助AC自动机拓扑排序优化,悬赏1关
查看原帖
求助AC自动机拓扑排序优化,悬赏1关
409774
Maysoul楼主2023/5/22 20:29

优化思路就是第一篇题解的。

其余的就是裸的AC自动机板子

调的很头疼了,特来求助一下

//2023/5/22
//别着急,先通读一遍题目
//别忘了开long long
//写完先看一遍怎么降复杂度
//要么开全局变量要么给定初值
//想想看,有什么情况需要特判
//看看数组开的够不够大
//std::ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
#include<bits/stdc++.h>
using namespace std;
const int MAXN=1e6+10;
struct trietree{
	int fall=0;
	int child[26]={0};
	int cnt=0;
	int ans=0;
}trie[MAXN];
int tcnt=0; 
int mp[MAXN];
int du[MAXN];
void insert(string &s,int i)
{
	int rootid=0;
	for (char c:s)
	{
		int cid=c-'a';
		if(trie[rootid].child[cid]==0)
		{
			trie[rootid].child[cid]=++tcnt;
		}
		rootid=trie[rootid].child[cid];
	}
	if(!trie[rootid].cnt) trie[rootid].cnt=i;
	mp[i]=trie[rootid].cnt;
}
queue<int> que;
void getfall()
{
	int rootid=0;
	for (int i=0;i<26;i++)
	{
		if(trie[rootid].child[i])
		{
			que.push(trie[rootid].child[i]);
		}
	}
	while(que.size())
	{
		rootid=que.front();
		que.pop();
		for (int i=0;i<26;i++)
		{
			if(trie[rootid].child[i])
			{
				que.push(trie[rootid].child[i]);
				du[trie[rootid].fall]++;
				trie[trie[rootid].child[i]].fall=trie[trie[rootid].fall].child[i];
			}
			else
			{
				trie[rootid].child[i]=trie[trie[rootid].fall].child[i];
			}
		}
	}
}
int vis[MAXN];
void ACmachine(string &s)
{
	int rootid=0;
	for (int i=0;i<s.length();i++)
	{
		int id=s[i]-'a';
		rootid=trie[rootid].child[id];
		trie[rootid].ans++;
	}
}
void topsort()
{
	for (int i=0;i<=tcnt;i++)
	{
		if(du[i]==0)
		{
			que.push(i);
		}
	}
	while(!que.empty())
	{
		int rootid=que.front();
		que.pop();
		vis[trie[rootid].cnt]=trie[rootid].ans;
		int v=trie[rootid].fall;
		du[v]--;
		trie[v].ans+=trie[rootid].ans;
		if(du[v]==0) que.push(v);
	}
}
int main()
{
	int n;
	string s;
	cin>>n;
	for (int i=1;i<=n;i++)
	{
		cin>>s;
		insert(s,i);
	}	
	getfall();
	cin>>s;
	ACmachine(s);
	topsort();
	for (int i=1;i<=n;i++)
	{
		cout<<vis[mp[i]]<<endl;
	}
	return 0;
}

2023/5/22 20:29
加载中...