跟这道题一模一样,而且不强制在线,所以先打标记然后上传就行了.
CODE
#include<bits/stdc++.h>
using namespace std;
char cb[1<<15],*cs=cb,*ct=cb;
#define getc() (cs==ct&&(ct=(cs=cb)+fread(cb,1,1<<15,stdin),cs==ct)?0:*cs++)
template<class T>inline void read(T &res) {
char ch; int flg = 1; while(!isdigit(ch=getchar()))if(ch=='-')flg=-flg;
for(res=ch-'0';isdigit(ch=getchar());res=res*10+ch-'0'); res*=flg;
}
const int MAXN = 1000205;
const int C = 27;
int n, m, node[MAXN];
struct Aho_Corasick {
int ch[MAXN][C], fail[MAXN], tot, q[MAXN];
inline int insert(char *s) {
int r = 0, indx;
while(*s) {
if(!ch[r][indx=(*s++)-'a'])
ch[r][indx] = ++tot;
r = ch[r][indx];
}
return r;
}
inline void build() {
int r = 0, head = 0, tail = 0;
fail[q[tail++]=r] = -1;
while(head < tail) {
r = q[head++];
for(int v, indx = 0; indx < C; ++indx)
if((v=ch[r][indx])) {
q[tail++] = v;
fail[v] = (r == 0 ? 0 : ch[fail[r]][indx]);
}
else ch[r][indx] = (r == 0 ? 0 : ch[fail[r]][indx]);
}
}
int ans[MAXN];
void modify(char *s) {
int r = 0, indx;
while(*s)
++ans[r = ch[r][indx=(*s++)-'a']];
//直接用上面的队列
for(int i = tot; i; --i)
ans[fail[q[i]]] += ans[q[i]];
}
}trie;
char s[MAXN], S[MAXN];
int main() {
read(n); int now = 0;
for(int i = 1; i <= n; ++i) {
scanf("%s", s), node[i] = trie.insert(s);
for(int j = 0; s[j]; ++j)
S[now++] = s[j];
S[now++] = 'z'+1; //插一个特殊符号
}
trie.build();
trie.modify(S);
for(int i = 1; i <= n; ++i) printf("%d
", trie.ans[node[i]]);
}