题意:链接

方法:AC自己主动机与fail树性质

解析:复习AC自己主动机的第一道题?(真正的第一题明明是又一次写了遍hdu2222!

)

这题说实话第一眼看上去就是个sb题,仅仅要建出来自己主动机。然后搜fail树即可了。只是看完140142的博客貌似这样会T?只是他也过了是什么鬼?反正想想后没想到什么好的方法就去看了看题解。写题解的大牛们的思路能够概括成一句话,也就是fail树的性质:

你要查找某个串的出现次数则为该串的根节点在fail树上出现的次数之和。

恩知道了这个性质后(能够yy下),这道题能够再来个优化,也就是在build的时候能够将这个整个树的bfs序求出来,又由于fail节点都是后面的连到前面的,所以无后效性,也就是说,我们能够从这个栈的栈顶抽元素,并将他的end值加到他的fail节点上。这样也许会快非常多?

输出部分就是我们之前说的了。找到每一个串的根节点。询问他的end值即可。

代码:


#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 210
#define M 1000100
using namespace std;
int n,L,root,size;
char s[N][M];
int next[M][27],fail[M],end[M],q[M];
int newnode()
{
for(int i=1;i<=26;i++)next[size][i]=-1;
end[size++]=0;
return size-1;
}
void init()
{
size=0;
root=newnode();
}
void ins()
{
int l=strlen(s[L]);
int now=root;
for(int i=0;i<l;i++)
{
int tmp=s[L][i]-'a'+1;
if(next[now][tmp]==-1)next[now][tmp]=newnode();
now=next[now][tmp];
end[now]++;
}
}
void build()
{
int LL=0,RR=-1;
for(int i=1;i<=26;i++)
{
if(next[root][i]==-1)next[root][i]=root;
else
{
fail[next[root][i]]=root;
q[++RR]=next[root][i];
}
}
while(LL<=RR)
{
int u=q[LL++];
for(int i=1;i<=26;i++)
{
if(next[u][i]==-1)next[u][i]=next[fail[u]][i];
else
{
fail[next[u][i]]=next[fail[u]][i];
q[++RR]=next[u][i];
}
}
}
for(int i=RR;i>=0;i--)
{
end[fail[q[i]]]+=end[q[i]];
}
}
int main()
{
init();
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%s",s[i]);
L++;
ins();
}
build();
L=1;
for(int i=1;i<=n;i++)
{
int k=root;
int l=strlen(s[i]);
for(int j=0;j<l;j++)k=next[k][s[i][j]-'a'+1];
printf("%d\n",end[k]);
}
}

BZOJ 3172 [Tjoi2013]单词 AC自己主动机(fail树)的更多相关文章

  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自动机】

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

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

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

  6. BZOJ 1212 HNOI2004 L语言 AC自己主动机(Trie树)+动态规划

    标题效果:给定词的列表,并m串 每个字符串q个最长前缀,这个前缀可满足拆分成一些字符串 这些字符串中存在的词汇太 再也不怕错误的数据范围--有一个很明显Trie树能解决的问题竟然被我写的AC自己主动机 ...

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

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

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

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

  9. ●BZOJ 3172 [Tjoi2013]单词

    题链: http://www.lydsy.com/JudgeOnline/problem.php?id=3172 题解: 把单词逐个接起来,中间用互不相同的字符连接,并记录下每个单词的首字母在串中的位 ...

随机推荐

  1. Qt QByteArray或者Char转十六进制 QString

    1.QByteArray转十六进制 QByteArray buff = sp->readAll(); qDebug() << buff.toHex() << " ...

  2. AIM Tech Round 4 (Div. 1) C - Upgrading Tree 构造 + 树的重心

    C - Upgrading Tree 我发现我构造题好弱啊啊啊. 很明显能想到先找到重心, 然后我们的目标就是把所有点接到重心的儿子上,让重心的儿子子树变成菊花图, 这个先把重心到儿子的边连到 i , ...

  3. SpringBoot中使用纯scala进行开发 配置教程 非常简单的案例

    新建项目 建好之后 建一个叫scala的文件夹 并把它标记为root文件夹 修改pom.xml文件 复制粘贴如下内容: 添加的插件的作用,如果不添加,在新建文件的时候右键只能新建java的文件,无法创 ...

  4. P1280 尼克的任务 线性DP

    题目描述 尼克每天上班之前都连接上英特网,接收他的上司发来的邮件,这些邮件包含了尼克主管的部门当天要完成的全部任务,每个任务由一个开始时刻与一个持续时间构成. 尼克的一个工作日为N分钟,从第一分钟开始 ...

  5. 035 spark与hive的集成

    一:介绍 1.在spark编译时支持hive 2.默认的db 当Spark在编译的时候给定了hive的支持参数,但是没有配置和hive的集成,此时默认使用hive自带的元数据管理:Derby数据库. ...

  6. Centos下命令行编译MapReduce代码(Java)并打包在Hadoop中执行

    前提条件:搭建好Hadoop系统 新建文件夹:input  和  output hdfs dfs -mkdir /inputhdfs dfs -mkdir /output 查看文件系统 hdfs df ...

  7. oi初级数学知识

    一.先是一些整除的性质: •整除:若a=bk,其中a,b,k都是整数,则b整除a,记做b|a. •也称b是a的约数(因数),a是b的倍数 •显而易见的性质: •1整除任何数,任何数都整除0 •若a|b ...

  8. 关于dubbo和zookeeper 注册中心

    Dubbo采用全Spring配置方式,透明化接入应用,对应用没有任何API侵入,只需用Spring加载Dubbo的配置即可,Dubbo基于Spring的Schema扩展进行加载.如果不想使用Sprin ...

  9. luogu [TJOI2007]线段

    题目链接 luogu [TJOI2007]线段 题解 dp[i][0/1]第i行在左/右端点的最短路 瞎转移 代码 #include<bits/stdc++.h> using namesp ...

  10. Prim算法和Kruskal算法

       Prim算法和Kruskal算法都能从连通图找出最小生成树.区别在于Prim算法是以某个顶点出发挨个找,而Kruskal是先排序边,每次选出最短距离的边再找. 一.Prim(普里姆算法)算法: ...