求求了,暗恋的女生给我说只要过了这道题就答应我!!
查看原帖
求求了,暗恋的女生给我说只要过了这道题就答应我!!
297806
Demeanor_Roy楼主2023/3/29 20:48

标题党,AC 自动机求调。

#include<bits/stdc++.h>
using namespace std;
#define LL long long
const int N=1e6+10,M=210;
int n,id,q[N],len[M],ans[M],sum[N],fail[N],tr[N][26];
int h[N],e[N],ne[N],din[N],idx;
char t[M][N];
inline void add(int a,int b){e[idx]=b;ne[idx]=h[a],h[a]=idx++;}
inline void insert(int cur)
{
	scanf("%s",t[cur]+1);len[cur]=strlen(t[cur]+1);
	int p=0;
	for(int i=1;i<=len[cur];i++)
	{
		int to=t[cur][i]-'a';
		if(!tr[p][to]) tr[p][to]=++id;
		p=tr[p][to];
	}
	ans[cur]=p;
}
inline void build(int p,int fr)
{
	for(int i=0;i<26;i++)
	{
		if(!tr[p][i]) continue;
		int now=fr;
		while(now&&!tr[now][i]) now=fail[now];
		fail[tr[p][i]]=now=(tr[now][i]?tr[now][i]:now);
		build(tr[p][i],now);
	}
}
inline void solve(int cur)
{
	for(int i=1,p=0;i<=len[cur];i++)
	{
		int to=t[cur][i]-'a';
		while(p&&!tr[p][to]) p=fail[p];
		if(tr[p][to]) p=tr[p][to];sum[p]++;
	}
}
int main()
{
	memset(h,-1,sizeof h);
	scanf("%d",&n);
	for(int i=1;i<=n;i++) insert(i);
	for(int i=0;i<26;i++) if(tr[0][i]) build(tr[0][i],0);
	for(int i=1;i<=n;i++) solve(i);
	int head=0,tail=-1;
	for(int i=1;i<=id;i++) if(fail[i]) add(i,fail[i]),din[fail[i]]++;
	for(int i=1;i<=id;i++) if(!din[i]) q[++tail]=i;
	while(head<=tail)
	{
		int now=q[head++];
		for(int i=h[now];~i;i=ne[i]) 
		{
			sum[e[i]]+=sum[now];
			din[e[i]]--;
			if(!din[e[i]]) q[++tail]=e[i];
		}
	}
	for(int i=1;i<=n;i++) printf("%d\n",sum[ans[i]]);
	return 0;	
} 
2023/3/29 20:48
加载中...