bzoj 3172 单词 ac自动机|后缀数组
题目大意:
给定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自动机|后缀数组的更多相关文章
- 字符串的模板 Manacher kmp ac自动机 后缀数组 后缀自动机
为何scanf("%s", str)不需要&运算 经常忘掉的字符串知识点,最好不加&,不加&最标准,指针如果像scanf里一样加&是错的,大概是未定 ...
- Trie树&kmp&AC自动机&后缀数组&Manacher
Trie 计数+Trie,读清题意很重要 https://vjudge.net/problem/UVALive-5913 kmp AC自动机 模板:https://vjudge.net/problem ...
- (17/34)AC自动机/后缀数组/后缀自动机(施工中)
快补题别再摸鱼了(17/34) 1.AC自动机 #define maxnode 1000010 #define maxsize 26 struct ahocT{ int ch[maxnode][max ...
- BZOJ 3172: [Tjoi2013]单词 [AC自动机 Fail树]
3172: [Tjoi2013]单词 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 3198 Solved: 1532[Submit][Status ...
- BZOJ 3172 单词(ac自动机)
题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=3172 题意:给出n个单词.输出每个单词在所有单词中一共出现多少次? 思路:首先将所有单词 ...
- bzoj 3172: [Tjoi2013]单词 AC自动机
3172: [Tjoi2013]单词 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/pr ...
- 【BZOJ 3172】[Tjoi2013]单词 AC自动机
关于AC自动机:一个在kmp与Trie的基础上建立的数据结构,关键在于Trie树结构与fail指针,他们各有各的应用.在AC自动机里最典型的就是多串匹配,原本效率为O(n*l+n*l+m*l),(n是 ...
- BZOJ 2905: 背单词 AC自动机+fail树+dfs序+线段树
Description 给定一张包含N个单词的表,每个单词有个价值W.要求从中选出一个子序列使得其中的每个单词是后一个单词的子串,最大化子序列中W的和. Input 第一行一个整数TEST,表示数据组 ...
- bzoj 3796: Mushroom追妹纸 AC自动机+后缀自动机+dp
题目大意: 给定三个字符串s1,s2,s3,求一个字符串w满足: w是s1的子串 w是s2的子串 s3不是w的子串 w的长度应尽可能大 题解: 首先我们可以用AC自动机找出s3在s1,s2中出现的位置 ...
随机推荐
- 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 ...
- 微信小程序-WebSocket
wx.connectSocket(OBJECT) 创建一个 WebSocket 连接:一个微信小程序同时只能有一个 WebSocket 连接,如果当前已存在一个 WebSocket 连接,会自动关闭该 ...
- linux实用命令语句
du -sh ./* 作用:检索当前目录下的所有文件及文件夹的大小,或者"du -sh 文件名/*","du -sh 文件夹名/*"查看某个文件或文件夹的大小 ...
- Web开发中20个很有用的CSS库
来源: 微信公众号文章 在过去的几年中,CSS已经成为一大部分开发者和设计者的最爱,因为它提供了一系列功能和特性.每个月都有无数个围绕CSS的工具被开发者发布以简化WEB开发.像CSS库,框架,应用这 ...
- 自定义一个类似UIAlertView的弹出框
这个是和UIAlertView类似,但是可以自定义view的样式废话不多说,上代码: 首先第一步:创建一个继承自View的类如: #import <UIKit/UIKit.h> @clas ...
- public private, protect. 以及继承。 草稿。
#include <iostream>#include <thread>#include <memory> // | 父类的public成员 | 父类的protec ...
- Python之路 day3 全局变量、局部变量
#!/usr/bin/env python # -*- coding:utf-8 -*- #Author:ersa """ 全局与局部变量 在子程序中定义的变量称为局部变 ...
- Sudoku 数独游戏
#include<iostream> using namespace std; bool heng(int **sudo, int a, int b, int value) { bool ...
- 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版本 ...
- 安装Python时遇到如下问题,解决方案
~$ sudo apt-get install python-pip 正在读取软件包列表... 完成 正在分析软件包的依赖关系树 正在读取状态信息... 完成 python-pip 已经是最新的版本了 ...