【AC自动机/fail树】BZOJ3172- [Tjoi2013]单词
【题目大意】
http://www.lydsy.com:808/JudgeOnline/problem.php?id=3172
某人读论文,一篇论文是由许多单词组成。但他发现一个单词会在论文中出现很多次,现在想知道每个单词分别在论文中出现多少次。
【思路】
第一次写fail树。首先建立AC自动机,对于路径上的每一个点sum++,表示出现的次数。fail指针指向的后缀,如果从fail指针指向的点开始方向建立fail树,其子树的sum之和就等于以它作为后缀的串的总数,相当于它在文章中出现的个数。
*fail树好神奇啊,不过E数组到底应该开多大呢?struct类型的数组到底应该怎么计算空间呢?困惑。
【错误名】
AC自动机的fail指针建立错了…详细见注释。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
#define Lnum 26
using namespace std;
const int MAXN=;
const int MAXLEN=;
int n;
int cnt=;
struct ACauto
{
ACauto* next[Lnum];
ACauto* fail;
int id,sum;
ACauto()
{
for (int i=;i<Lnum;i++) next[i]=NULL;
fail=NULL;
sum=;
id=++cnt;
}
};
ACauto* rt=new ACauto();
ACauto* node[MAXN];
struct edge
{
ACauto* to;
edge* next;
edge()
{
to=NULL;
next=NULL;
}
};
edge* E[MAXLEN*Lnum]; void addedge(ACauto* u,ACauto* v)
{
edge* tmp=new edge;
tmp->to=v;
tmp->next=E[u->id];
E[u->id]=tmp;
} void insert(ACauto* rt,char* str,int order)
{
ACauto* tmp=rt;
int len=strlen(str);
for (int i=;i<len;i++)
{
int index=str[i]-'a';
if (tmp->next[index]==NULL)
tmp->next[index]=new ACauto();
tmp=tmp->next[index];
tmp->sum++;
}
node[order]=tmp;
} void build(ACauto* rt)
{
queue<ACauto*> que;
que.push(rt);
while (!que.empty())
{
ACauto* head=que.front();que.pop();
for (int i=;i<Lnum;i++)
{
if (head->next[i]!=NULL)
{
if (head==rt)
{
head->next[i]->fail=rt;
addedge(rt,head->next[i]);
}
else
{
ACauto* tmp=head->fail;
while (tmp!=NULL)
{
if (tmp->next[i]!=NULL)
{
head->next[i]->fail=tmp->next[i];
//指向最长的后缀,所以是tmp->next[i],而不是tmp
addedge(tmp->next[i],head->next[i]);
break;
}
else tmp=tmp->fail;
}
if (tmp==NULL)
{
head->next[i]->fail=rt;
addedge(rt,head->next[i]);
}
}
que.push(head->next[i]);
}
}
}
} void dfs(ACauto* rt)
{
for (edge* i=E[rt->id];i!=NULL;i=i->next)
{
dfs(i->to);
rt->sum+=i->to->sum;
}
} void init()
{
scanf("%d",&n);
char str[MAXLEN];
for (int i=;i<n;i++)
{
scanf("%s",str);
insert(rt,str,i);
}
build(rt);
} void getans()
{
dfs(rt);
for (int i=;i<n;i++) cout<<node[i]->sum<<endl;
} int main()
{
init();
getans();
return ;
}
【AC自动机/fail树】BZOJ3172- [Tjoi2013]单词的更多相关文章
- 【学习笔记】ac自动机&fail树
定义 解决文本串和多个模式串匹配的问题: 本质是由多个模式串形成的一个字典树,由tie的意义知道:trie上的每一个节点都是一个模式串的前缀: 在trie上加入fail边,一个节点fail边指向这个节 ...
- BZOJ3172[Tjoi2013]单词——AC自动机(fail树)
题目描述 某人读论文,一篇论文是由许多单词组成.但他发现一个单词会在论文中出现很多次,现在想知道每个单词分别在论文中出现多少次. 输入 第一个一个整数N,表示有多少个单词,接下来N行每行一个单词.每个 ...
- BZOJ 3172: [Tjoi2013]单词 [AC自动机 Fail树]
3172: [Tjoi2013]单词 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 3198 Solved: 1532[Submit][Status ...
- BZOJ2905: 背单词 AC自动机+fail树+线段树
$zjq$神犇一眼看出$AC$自动机 $Orz$ 直接就讲做法了 首先对每个串建出$AC$自动机 将$fail$树找到 然后求出$dfs$序 我们发现一个单词 $S_i$是$S_j$的子串当且仅当$S ...
- BZOJ 2905: 背单词 AC自动机+fail树+dfs序+线段树
Description 给定一张包含N个单词的表,每个单词有个价值W.要求从中选出一个子序列使得其中的每个单词是后一个单词的子串,最大化子序列中W的和. Input 第一行一个整数TEST,表示数据组 ...
- AC自动机 & Fail树 专题练习
Fail树就是AC自动机建出来的Fail指针构成的树. [bzoj3172][xsy1713]单词 题意 给定一些单词,求每个单词在所有单词里面的出现次数. 分析 构建Fail树,记录每个单词最后一个 ...
- BZOJ2434 [Noi2011]阿狸的打字机 【AC自动机 + fail树 + 树状数组】
2434: [Noi2011]阿狸的打字机 Time Limit: 10 Sec Memory Limit: 256 MB Submit: 3610 Solved: 1960 [Submit][S ...
- AC自动机fail树小结
建议大家学过AC自动机之后再来看这篇小结 fail树就是讲fail指针看做一条边连成的树形结构 fail指针在AC自动机中的含义是指以x为结尾的后缀在其他模式串中所能匹配的最长前缀的长度 所以在模式串 ...
- BZOJ 2434: [Noi2011]阿狸的打字机 [AC自动机 Fail树 树状数组 DFS序]
2434: [Noi2011]阿狸的打字机 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 2545 Solved: 1419[Submit][Sta ...
随机推荐
- 几种list集合的区别
SDK提供了有序集合接口java.util.List的几种实现,其中三种最为人们熟知的是Vector.ArrayList和LinkedList.有关这些List类的性能差别是一个经常被问及的问题.在这 ...
- Git命令文本手册
git init # 初始化本地git仓库(创建新仓库) git config --global user.name "xxx" # 配置用户名 git config --glob ...
- JavaScript获取HTML元素样式的方法(style、currentStyle、getComputedStyle)
一.style.currentStyle.getComputedStyle的区别 style只能获取元素的内联样式,内部样式和外部样式使用style是获取不到的. currentStyle可以弥补st ...
- Nginx 默认配置解析
# For more information on configuration, see: # * Official English Documentation: http://nginx.org/e ...
- 一致性hash算法小结
把服务器的IP或者主机名作为key对2^32求余,余数一定是2^32-1,然后放到(平行映射)0~2^32次方首尾相连的环上. 理想状态下服务器会均匀分布在这个环上,当数据存储时,依然把key对2 ...
- Swift开发学习(一):初始篇
http://blog.csdn.net/powerlly/article/details/29351103 Swift开发学习:初始篇 关于 苹果公司于WWDC2014(Apple Worldwid ...
- POJ3466(01背包变形)
Proud Merchants Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others) ...
- bootstrap,ECMA
前端UI(布局)框架 bootstrap Amaze UI BootStrap 全局css样式 栅格系统 container 容器 超小屏幕 手机 vw <768px 宽度 100% 小屏幕 平 ...
- Newtonsoft.Json 序列化和反序列化 以及时间格式 2
一.JSON使用JsonPropertyAttribute重命名属性名 1.先创建一个Movie对象,然后在其属性上添加JsonProperty,并指定重命名的名称.注意:属性Name和Directo ...
- P2654 原核生物培养
P2654 原核生物培养 题目描述 W教授最近正在研究一种原核生物,这种生物的生长方式很奇特,只能通过吃掉同类而生长.两个该种生物相遇,较大质量的会把较小的吃掉(相同的话就看RP了),吃掉后较大的生物 ...