查看代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e6+5;
const int mod = 1e9+7;
ll qpow(ll a,ll b){ll res=1;for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
struct graph
{
int head[maxn],nxt[maxn],to[maxn],w[maxn],sz;
void init(){memset(head,-1,sizeof(head));}
graph(){init();}
void push(int a,int b,int c){nxt[sz]=head[a],to[sz]=b,w[sz]=c,head[a]=sz++;}
int& operator[](const int a){return to[a];}
}g;
struct AC_automaton
{
int tree[maxn][26];
int fail[maxn];
int belong[maxn];
int cnt[maxn];
int tot;
void Insert(char *s,int k)
{
int root = 0;
for(int i = 0;s[i];++i){
int p = s[i]-'a';
if(!tree[root][p])tree[root][p]=++tot;
root=tree[root][p];
cnt[root]++;
}
belong[k]=root;
}
void get_fail()
{
queue<int>q;
for(int i = 0;i < 26;++i){
if(tree[0][i]){
q.push(tree[0][i]);
}
}
while(!q.empty()){
int now = q.front();
q.pop();
g.push(fail[now],now,0);
for(int i = 0;i < 26;++i){
if(!tree[now][i]){
tree[now][i]=tree[fail[now]][i];
}
else {
q.push(tree[now][i]);
fail[tree[now][i]]=tree[fail[now]][i];
}
}
}
}
void dfs(int now)
{
for(int i = g.head[now];~i;i = g.nxt[i]){
dfs(g[i]);
cnt[now]+=cnt[g[i]];
}
}
}ac;
char s[maxn];
int main()
{
#ifndef ONLINE_JUDGE
freopen("simple.in", "r", stdin);
freopen("simple.out", "w", stdout);
#endif
int n;
scanf("%d",&n);
for(int i = 1;i <= n;++i){
scanf("%s",s);
ac.Insert(s,i);
}
ac.get_fail();
ac.dfs(0);
for(int i = 1;i <= n;++i)printf("%d\n",ac.cnt[ac.belong[i]]);
return 0;
}