# 题目

## 3172: [Tjoi2013]单词

Time Limit: 10 Sec  Memory Limit: 512 MB
Submit: 3655  Solved: 1757
[Submit][Status][Discuss]

3
a
aa
aaa

6
3
1

# 题解

//TLE代码..........
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

struct Node
{
Node *fail;
Node *next[27];
int id;
Node()
{
fail = NULL;
id = 0;
memset(next,NULL,sizeof(next));
}
};
char T[205][1000005];
int _cnt[1005];
int l[1005];
int belong[1005];
void buildTrie(char *str,Node *root,int id)
{
Node *p = root,*q;
int len=l[id];
for(int i=0; i<len; i++)
{
int idx = str[i]-'a';
if(p->next[idx]==NULL) p->next[idx]=new Node();
p = p->next[idx];
}
if(p->id==0)
p->id = id;
belong[id]=p->id;
}
void build_AC_automation(Node *root)
{
Node* q[200005];
int pi=1,h=0;
root->fail = NULL;
q[++h]=root;
while(pi<=h)
{
Node *p = NULL;
Node *temp = q[pi];
pi++;
for(int i=0; i<27; i++)
{
if(temp->next[i]!=NULL)
{
if(temp==root) temp->next[i]->fail=root;
else
{
p=temp->fail;
while(p!=NULL)
{
if(p->next[i]!=NULL)
{
temp->next[i]->fail=p->next[i];
break;
}
p=p->fail;
}
if(p==NULL) temp->next[i]->fail=root;
}
q[++h]=temp->next[i];
}
}
}

}
void query(char *str,int li,Node *root)
{
Node *p = root;
int len=li;
for(int i=0; i<len; i++)
{
int idx = str[i]-'a';
while(p->next[idx]==NULL&&p!=root) p = p->fail;
p = p->next[idx];
p = (p==NULL)?root:p;
Node * temp = p;
while(temp!=root)
{
if(temp->id!=0)
_cnt[temp->id]++;
temp = temp->fail;
}
}
}
int main()
{
int n;
scanf("%d",&n);
Node *root = new Node();
for(int i=1; i<=n; i++)
{
scanf("%s",T[i]);
l[i]=strlen(T[i]);
buildTrie(T[i],root,i);
}
build_AC_automation(root);
for(int i=1;i<=n;i++)
query(T[i],l[i],root);
for(int i=1; i<=n; i++)
printf("%d\n",_cnt[belong[i]]);
return 0;
}

so  对于每一个fail指针不为root且NULL的点p（其实root可以不管它）

p->fail->cnt+=p->cnt;

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

struct Node
{
Node *fail;
Node *next[27];
int cnt;
Node()
{
fail = NULL;
cnt=0;
memset(next,NULL,sizeof(next));
}
};
Node *w[205];
char T[205][1000005];
int l[1005];
int belong[1005];
void buildTrie(char *str,Node *root,int id)
{
Node *p = root,*q;
int len=l[id];
for(int i=0; i<len; i++)
{
int idx = str[i]-'a';
if(p->next[idx]==NULL) p->next[idx]=new Node();
p = p->next[idx];
p->cnt++;
}
w[id]=p;
}
void build_AC_automation(Node *root)
{
Node* q[200005];
int pi=1,h=0;
root->fail = NULL;
q[++h]=root;
while(pi<=h)
{
Node *p = NULL;
Node *temp = q[pi];
pi++;
for(int i=0; i<27; i++)
{
if(temp->next[i]!=NULL)
{
if(temp==root) temp->next[i]->fail=root;
else
{
p=temp->fail;
while(p!=NULL)
{
if(p->next[i]!=NULL)
{
temp->next[i]->fail=p->next[i];
break;
}
p=p->fail;
}
if(p==NULL) temp->next[i]->fail=root;
}
q[++h]=temp->next[i];
}
}
}
for(int i=h;i>=1;i--)
if(q[i]->fail!=root&&q[i]->fail!=NULL)
q[i]->fail->cnt+=q[i]->cnt;
}
int main()
{
int n;
scanf("%d",&n);
Node *root = new Node();
for(int i=1;i<=n;i++)
{
scanf("%s",T[i]);
l[i]=strlen(T[i]);
buildTrie(T[i],root,i);
}
build_AC_automation(root);
for(int i=1; i<=n; i++)
printf("%d\n",w[i]->cnt);
return 0;
}

posted on 2017-03-18 15:12  void_zxh  阅读(123)  评论(0编辑  收藏  举报