关于AC自动机:一个在kmp与Trie的基础上建立的数据结构,关键在于Trie树结构与fail指针,他们各有各的应用。在AC自动机里最典型的就是多串匹配,原本效率为O(n*l+n*l+m*l),(n是模式串个数,m是匹配串长度,l是模式串平均长度),那么他的效率甚至有时不如多个kmp,虽然很好被卡但平均效率还是不错的。如果在此基础上加上last指针,作用为减少匹配过程中不必要的跳fail,那么就会好一些,但是效率不会有显著的提升而且仍然很好卡,目前为O(n*l+n*l+m*n)。在此基础上我们就可以加上Trie图,Trie图作用就是加快建fail以及在匹配过程中的转移,这时效率就会有不错的提升,建fail的时间复杂度也就更有保证,但是仍然会被卡,目前为O(n*l+n*l+m*n)。到此为止我们的时间复杂度已经是比较优秀的了,但是我们还可以让他更加优秀,我们可以在加上fail树,关于fail树,那么我们在匹配过程中就可以省去跳跃的过程,现在我们的时间复杂度已经到了O(n*l+n*l+m+n*l),已经有了巨大的飞跃,而且基本不会被卡。

我的程序是倒数第二层优化的,慢死。

#include <vector>
#include <cstring>
#include <cstdio>
#include <iostream>
const int N=;
char s[][N];
struct Trie{
Trie *ch[],*fail,*last;
std::vector<int> mem;
}node[N+],*root,*q[N+];
int n,sz,sum[];
inline Trie *newnode(){
return &node[++sz];
}
inline void insert(char *w,int id){
Trie *p=root;
for(int i=;w[i];i++){
if(p->ch[w[i]-'a']==NULL)p->ch[w[i]-'a']=newnode();
p=p->ch[w[i]-'a'];
}
p->mem.push_back(id);
}
inline void build(){
q[]=root;
for(int i=,j=;i<=j;i++)
for(int l=;l<;l++)
if(q[i]->ch[l]){
q[++j]=q[i]->ch[l];
q[j]->fail=q[i]==root?root:q[i]->fail->ch[l];
q[j]->last=q[j]->fail->mem.size()?q[j]->fail:q[j]->fail->last;
}
else
q[i]->ch[l]=q[i]==root?root:q[i]->fail->ch[l];
}
inline void read(){
scanf("%d",&n),root=node;
for(int i=;i<=n;i++)
scanf("%s",s[i]),insert(s[i],i);
build();
}
inline void work(){
for(int k=;k<=n;k++){
Trie *now=root;
for(int i=;s[k][i];i++){
now=now->ch[s[k][i]-'a'];
for(int j=;j<now->mem.size();j++)
sum[now->mem[j]]++;
for(Trie *p=now->last;p;p=p->last)
for(int j=;j<p->mem.size();j++)
sum[p->mem[j]]++;
}
}
}
inline void print(){
for(int i=;i<=n;i++)
printf("%d\n",sum[i]);
}
int main(){
read();
work();
print();
}

【BZOJ 3172】[Tjoi2013]单词 AC自动机的更多相关文章

  1. BZOJ 3172: [Tjoi2013]单词 [AC自动机 Fail树]

    3172: [Tjoi2013]单词 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 3198  Solved: 1532[Submit][Status ...

  2. bzoj 3172: [Tjoi2013]单词 AC自动机

    3172: [Tjoi2013]单词 Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/pr ...

  3. BZOJ 3172 [Tjoi2013]单词 AC自动机Fail树

    题目链接:[http://www.lydsy.com/JudgeOnline/problem.php?id=3172] 题意:给出一个文章的所有单词,然后找出每个单词在文章中出现的次数,单词用标点符号 ...

  4. BZOJ 3172 [Tjoi2013]单词 AC自己主动机(fail树)

    题意:链接 方法:AC自己主动机与fail树性质 解析:复习AC自己主动机的第一道题?(真正的第一题明明是又一次写了遍hdu2222! ) 这题说实话第一眼看上去就是个sb题,仅仅要建出来自己主动机. ...

  5. BZOJ 3172([Tjoi2013]单词-后缀数组第一题+RMQ)

    3172: [Tjoi2013]单词 Time Limit: 10 Sec   Memory Limit: 512 MB Submit: 268   Solved: 145 [ Submit][ St ...

  6. [BZOJ 3172] [Tjoi2013] 单词 【AC自动机】

    题目链接:BZOJ - 3172 题目分析: 题目要求求出每个单词出现的次数,如果把每个单词都在AC自动机里直接跑一遍,复杂度会很高. 这里使用AC自动机的“副产品”——Fail树,Fail树的一个性 ...

  7. bzoj 3172: [Tjoi2013]单词【AC自动机】

    一眼AC自动机,就是先把串建一个自动机,标记每个串在自动机上的位置,然后加上间隔符连成一个串在自动机上跑,每跑到一个点就说明这个串以及它到root的所有点表示的串都要被更新一次 先在点上打上标记,最后 ...

  8. 【BZOJ3172】[Tjoi2013]单词 AC自动机

    [BZOJ3172][Tjoi2013]单词 Description 某人读论文,一篇论文是由许多单词组成.但他发现一个单词会在论文中出现很多次,现在想知道每个单词分别在论文中出现多少次. Input ...

  9. bzoj 3172 [Tjoi2013]单词(fail树,DP)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=3172 [题意] 题目的意思是这样的,给若干个单词,求每个单词在这一堆单词中的出现次数. ...

随机推荐

  1. elasticsearch 5.x 系列之五 数据导入导出

    一.首先给大家发一个福利,分享一个elasticsearch 数据导出工具. esm github 源码地址: https://github.com/medcl/esm 下载编译好的对应elastic ...

  2. 652. Find Duplicate Subtrees

    /** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode ...

  3. R语言绘图:ggplot2绘制ROC

    使用ggplot2包绘制ROC曲线 rocplot<- function(pred, truth, ...){ predob<- prediction(pred, truth) #打印AU ...

  4. C++ vector二维数组

    C++ 构建二维动态数组 int **p; p = ]; //注意,int*[10]表示一个有10个元素的指针数组 ; i < ; ++i) { p[i] = ]; } 这样就构成10*5的数组 ...

  5. Tensorflow之安装GPU版错误集合

        在根据教程http://blog.csdn.net/sb19931201/article/details/53648615安装好全部的时候,却无情的给我抛了几个错: 1.AttributeEr ...

  6. Oracle错误记录

    1 SQLPlus无法登陆oracle,PLSql可以登陆,报错ORA-12560 环境变量 右击计算机属性-->高级系统设置-->高级-->环境变量-->系统变量--> ...

  7. Android使用butterknife注解出现nullPointerException解决

    1.下载butterknife加入到你的libs中,构建到你的项目中,此时还不能注解成功,必须进行2配置 2.选择你的项目右键---->properties----->java compi ...

  8. 介绍PHP的自动加载

    昨天面试被问到了 PHP 的自动加载机制,因为很多概念模糊啦,没回答好,今天特意来总结一下. include 和 require 是PHP中引入文件的两个基本方法,但是每个脚本的开头,都需要包含(in ...

  9. sqlserver一次性删除master数据库中的所有用户添加的表

    use master; go sp_msforeachtable @command1="drop table ?" go

  10. SPOJ 694

    题面 题意: 给一个字符串,求它有多少个不同的子串 多组数据. Solution : 模板题,用所有的减去重复的即可. #include <cstdio> #include <alg ...