这波复习AC机,这道题很久之前就看过了,但是呢以前一看到字符串的题就是烦,现在写好像也不是很难。(途中艰辛的被企鹅和肉丝狂D,最后还是A了 :)
这题就是直接把单词插进树里,然后宽搜完倒着更新就行了。
#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> using namespace std; char ss[1100000];int id[210]; struct Trie { int w[30],fail,f; }tr[1100000];int trlen; void maketree(int ID) { int now=0,len=strlen(ss+1); for(int i=1;i<=len;i++) { int x=ss[i]-‘a‘+1; if(tr[now].w[x]==0)tr[now].w[x]=++trlen; now=tr[now].w[x]; tr[now].f++; } id[ID]=now; } int list[1100000]; void bfs() { int head=1,tail=2;list[1]=0; while(head!=tail) { int now=list[head]; for(int x=1;x<=26;x++) { if(tr[now].w[x]!=0) { int son=tr[now].w[x]; if(now==0)tr[son].fail=0; else { int p=tr[now].fail; while(p!=0&&tr[p].w[x]==0)p=tr[p].fail; tr[son].fail=tr[p].w[x]; } list[tail]=son; tail++; } } head++; } for(int i=tail;i;i--)tr[tr[list[i]].fail].f+=tr[list[i]].f; } int main() { int n; scanf("%d",&n); trlen=0; for(int i=1;i<=n;i++) { scanf("%s",ss+1); maketree(i); }bfs(); for(int i=1;i<=n;i++)printf("%d\n",tr[id[i]].f); return 0; }