题目大意:

给定n个字符串连成了一篇文章,问每个字符串在这篇文章中出现的次数,可重复覆盖

这里ac自动机和后缀数组都可以做

当然后缀数组很容易就解决,但是相对时间消耗高

这里就只讲ac自动机了

将每个字符串放入ac自动机中,这里需要记录到达每个ac自动机上的节点出现这个状态有多少次

而我们添加字符串进入的时候,应该是把经过的每个节点的val都++,说明这个字符串多出现了一次这个值

然后因为自己用字符串在ac自动机上走肯定是到达离root最近的点,也就是说有很多的点会不断通过fail指针指向他,而这些点都是包含了这个字符串的

那也就是说我们需要考虑 val[fail[i]] += val[i]

这里一定是需要从最底层的点不断fail上来,我们需要找到一个合适的更新val点的顺序

可以考虑在我们构建后缀自动机的时候我们采用的是利用队列bfs的过程,那也就是说进入的点是符合最大长度从小到大的性质的

而fail指向的总是比它长度更小的点,所以根据进入队列的点的逆顺序来更新val即可

也就是每次点进队列都 que[cnt++] = u;

最后

for(int i=sz-1 ; i>0 ; i--)
  val[fail[que[i]]]+=val[que[i]];

 #include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
#include <iostream>
#include <algorithm>
#include <map>
using namespace std;
#define clr(x) memset(x , 0 , sizeof(x))
#define set(x) memset(x , -1 , sizeof(x))
typedef long long LL ; const int CHAR_SIZE = ;
const int MAX_SIZE = ;
const int M = ; struct AC_Machine{
int ch[MAX_SIZE][CHAR_SIZE] , val[MAX_SIZE] , fail[MAX_SIZE] , que[MAX_SIZE];
int sz;
bool vis[MAX_SIZE];
void init(){
sz = ;
clr(ch[]) , clr(val) , clr(vis);
} int insert(string s){
int n = s.length();
int u= ;
for(int i= ; i<n ; i++){
int c = s[i]-'a';
if(!ch[u][c]){
clr(ch[sz]) , val[sz]=;
ch[u][c] = sz++;
}
u = ch[u][c];
val[u]++;
}
return u;
} void get_fail(){
queue<int> Q;
fail[] = ;
int cnt = ;
for(int c= ; c<CHAR_SIZE ; c++){
int u = ch[][c];
if(u){Q.push(u);fail[u]=,que[cnt++]=u;}
}
while(!Q.empty()){
int r = Q.front();
Q.pop();
for(int c= ; c<CHAR_SIZE ; c++){
int u = ch[r][c];
if(!u){ch[r][c] = ch[fail[r]][c]; continue;}
fail[u] = ch[fail[r]][c];
Q.push(u);
que[cnt++]=u;
}
}
}
void updateVal(){
for(int i=sz- ; i> ; i--)
val[fail[que[i]]]+=val[que[i]];
}
}ac;
int n , pos[];
string s[]; int main()
{
// freopen("a.in" , "r" , stdin);
// freopen("out.txt" , "w" , stdout);
scanf("%d" , &n);
ac.init();
for(int i= ; i<n ; i++){
cin>>s[i];
pos[i] = ac.insert(s[i]);
}
ac.get_fail();
ac.updateVal();
for(int i= ; i<n ; i++)
printf("%d\n" , ac.val[pos[i]]);
return ;
}

bzoj 3172 单词 ac自动机|后缀数组的更多相关文章

  1. 字符串的模板 Manacher kmp ac自动机 后缀数组 后缀自动机

    为何scanf("%s", str)不需要&运算 经常忘掉的字符串知识点,最好不加&,不加&最标准,指针如果像scanf里一样加&是错的,大概是未定 ...

  2. Trie树&kmp&AC自动机&后缀数组&Manacher

    Trie 计数+Trie,读清题意很重要 https://vjudge.net/problem/UVALive-5913 kmp AC自动机 模板:https://vjudge.net/problem ...

  3. (17/34)AC自动机/后缀数组/后缀自动机(施工中)

    快补题别再摸鱼了(17/34) 1.AC自动机 #define maxnode 1000010 #define maxsize 26 struct ahocT{ int ch[maxnode][max ...

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

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

  5. BZOJ 3172 单词(ac自动机)

    题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=3172 题意:给出n个单词.输出每个单词在所有单词中一共出现多少次? 思路:首先将所有单词 ...

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

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

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

    关于AC自动机:一个在kmp与Trie的基础上建立的数据结构,关键在于Trie树结构与fail指针,他们各有各的应用.在AC自动机里最典型的就是多串匹配,原本效率为O(n*l+n*l+m*l),(n是 ...

  8. BZOJ 2905: 背单词 AC自动机+fail树+dfs序+线段树

    Description 给定一张包含N个单词的表,每个单词有个价值W.要求从中选出一个子序列使得其中的每个单词是后一个单词的子串,最大化子序列中W的和. Input 第一行一个整数TEST,表示数据组 ...

  9. bzoj 3796: Mushroom追妹纸 AC自动机+后缀自动机+dp

    题目大意: 给定三个字符串s1,s2,s3,求一个字符串w满足: w是s1的子串 w是s2的子串 s3不是w的子串 w的长度应尽可能大 题解: 首先我们可以用AC自动机找出s3在s1,s2中出现的位置 ...

随机推荐

  1. Cheatsheet: 2016 03.01 ~ 03.31

    JAVA Quick Java 8 or Java 7 Dev Environments With Docker Printing arrays by hacking the JVM Mobile H ...

  2. 微信小程序-WebSocket

    wx.connectSocket(OBJECT) 创建一个 WebSocket 连接:一个微信小程序同时只能有一个 WebSocket 连接,如果当前已存在一个 WebSocket 连接,会自动关闭该 ...

  3. linux实用命令语句

    du -sh ./* 作用:检索当前目录下的所有文件及文件夹的大小,或者"du -sh 文件名/*","du -sh 文件夹名/*"查看某个文件或文件夹的大小 ...

  4. Web开发中20个很有用的CSS库

    来源: 微信公众号文章 在过去的几年中,CSS已经成为一大部分开发者和设计者的最爱,因为它提供了一系列功能和特性.每个月都有无数个围绕CSS的工具被开发者发布以简化WEB开发.像CSS库,框架,应用这 ...

  5. 自定义一个类似UIAlertView的弹出框

    这个是和UIAlertView类似,但是可以自定义view的样式废话不多说,上代码: 首先第一步:创建一个继承自View的类如: #import <UIKit/UIKit.h> @clas ...

  6. public private, protect. 以及继承。 草稿。

    #include <iostream>#include <thread>#include <memory> // | 父类的public成员 | 父类的protec ...

  7. Python之路 day3 全局变量、局部变量

    #!/usr/bin/env python # -*- coding:utf-8 -*- #Author:ersa """ 全局与局部变量 在子程序中定义的变量称为局部变 ...

  8. Sudoku 数独游戏

    #include<iostream> using namespace std; bool heng(int **sudo, int a, int b, int value) { bool ...

  9. Elasticsearch5.0.1 + Kibana5.0.1 + IK 5.0.1安装记录

    最近工作需要,开始研究ES,当前ES的最新版本为5.0.1,从之前的2.x的版本号一下升级到5.x,主要是之前Elastic的产品版本号因为收购等原因很乱,ES 2.X版本的和Kibana 4.x版本 ...

  10. 安装Python时遇到如下问题,解决方案

    ~$ sudo apt-get install python-pip 正在读取软件包列表... 完成 正在分析软件包的依赖关系树 正在读取状态信息... 完成 python-pip 已经是最新的版本了 ...