其实这显然是一道AC自动机裸题,这里补上后缀自动机做法。
#include <bits/stdc++.h>
using namespace std;
#define maxn 1100000
int n,len;
string s[500];
struct SAM
{
int a[maxn<<1][28],fa[maxn<<1],mx[maxn<<1],num[maxn<<1];
int du[maxn<<1],cnt,last;
void inti(){cnt=last=1;}
void insert(int c)
{
int p=last,np=last=++cnt;mx[np]=mx[p]+1;num[np]++;
while(!a[p][c]&&p) a[p][c]=np,p=fa[p];
if(!p) fa[np]=1;
else
{
int q=a[p][c];
if(mx[p]+1==mx[q]) fa[np]=q;
else
{
int nq=++cnt;mx[nq]=mx[p]+1;
memcpy(a[nq],a[q],sizeof(a[nq]));
fa[nq]=fa[q];
fa[np]=fa[q]=nq;
while(a[p][c]==q&&p) a[p][c]=nq,p=fa[p];
}
}
}
queue<int> q;
void cal()
{
for(int i=1;i<=cnt;i++)du[fa[i]]++;
for(int i=1;i<=cnt;i++)
if(!du[i])q.push(i);
while(!q.empty())
{
int t=q.front();q.pop();
if((--du[fa[t]])==0)q.push(fa[t]);
num[fa[t]]+=num[t];
}
}
}sam;
int main()
{
sam.inti();
scanf("%d",&n);
for(int i=1;i<=n;i++) cin>>s[i];
for(int i=1;i<=n;i++)
{
sam.last=1;
for(int j=0;j<s[i].size();j++)
{
sam.insert(s[i][j]-'a');
}
}
sam.cal();
for(int i=1;i<=n;i++)
{
int now=1;
for(int j=0;j<s[i].size();j++)
now=sam.a[now][s[i][j]-'a'];
printf("%d\n",sam.num[now]);
}
return 0;
}