模板汇总——AC自动机
AC自动机 模板题 HDU-2222 Keywords Search
#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define ULL unsigned LL
#define fi first
#define se second
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))
const int INF = 0x3f3f3f3f;
const LL mod = 1e9+;
typedef pair<int,int> pll;
const int N = 1e5+, M = 1e3;
char str[N*];
int trie[N*][];
int fair[N*];
int cnt[N*];
int tot = ;
void Insert(){
int rt = , len = strlen(str);
for(int i = ; i < len; i++){
int id = str[i] - 'a';
if(trie[rt][id] == ){
cnt[tot] = ;
fair[tot] = ;
trie[rt][id] = tot++;
}
rt = trie[rt][id];
}
cnt[rt]++;
}
void Build_tree(){
queue<int> q;
q.push();
int p;
while(!q.empty()){
int tmp = q.front();
q.pop();
for(int i = ; i < ; i++){
if(trie[tmp][i] != ){
if(tmp == )
fair[trie[tmp][i]] = ;
else{
p = fair[tmp];
while(p){
if(trie[p][i]){
fair[trie[tmp][i]] = trie[p][i];
break;
}
else p = fair[p];
}
if(!p) fair[trie[tmp][i]] = ;
}
q.push(trie[tmp][i]);
}
}
}
}
int Query(){
int rt = , ret = , len = strlen(str);
for(int i = ; i < len; i++){
int id = str[i] - 'a';
while(!trie[rt][id] && rt != ) rt = fair[rt];
rt = trie[rt][id];
if(rt == ) rt = ;
int tmp = rt;
while(tmp != ){
if(cnt[tmp] >= ){
ret += cnt[tmp];
cnt[tmp] = -;
}
else break;
tmp = fair[tmp];
}
}
return ret;
}
void init(){
for(int i = ; i < tot; i++){
for(int j = ; j < ; j++)
trie[i][j] = ;
}
tot = ;
}
int main(){
int T;
scanf("%d", &T);
while(T--){
init();
int n;
scanf("%d", &n);
while(n--){
scanf("%s", str);
Insert();
}
Build_tree();
scanf("%s", str);
printf("%d\n", Query());
}
return ;
}
2进制分组AC自动机
假如给你21个串: 分为 16+4+1,再添加一个串的时候,即21+1, 22 = 16+4+1+1 = 16 + 4 + 2。 这样每次加串之后只会有logn个操作,查询也变成logn操作, 对于同一个串建立fair指针的次数就少了。
#include<bits/stdc++.h>
using namespace std;
#define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
#define LL long long
#define ULL unsigned LL
#define fi first
#define se second
#define pb push_back
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))
typedef pair<int,int> pll;
const int INF = 0x3f3f3f3f;
const LL mod = (int)1e9+;
const int N = 3e5 + ;
struct Node{
static const int m = ;static const int KN = N;
int next[KN][m], fair[KN], tot = , mark[KN], mark1[KN], root[], cnt = , si[];
void Build(int x){
queue<int> q;
q.push(x);
int pos, p, v;
while(!q.empty()){
pos = q.front(), q.pop();
for(int i = ; i < m; i++){
if(!next[pos][i]) continue;
p = fair[pos]; v = next[pos][i];
while(p && !next[p][i]) p = fair[p];
if(p) fair[v] = next[p][i];
else fair[v] = x;
q.push(v);
mark1[v] = mark1[fair[v]] + mark[v];
}
}
}
void Add(char s[], char ch){
root[++cnt] = ++tot; si[cnt] = ;
int pos = root[cnt];
for(int i = ; s[i]; i++){
if(!next[pos][s[i]-ch]) next[pos][s[i]-ch] = ++tot;
pos = next[pos][s[i]-ch];
}
mark[pos]++;
while(si[cnt] == si[cnt-]){
Unit(root[cnt-], root[cnt]);
si[--cnt] *= ;
}
Build(root[cnt]);
}
int Query(char s[], char ch){
int pos, ret = ;
for(int id = ; id <= cnt; id++){
pos = root[id];
for(int i = ; s[i]; i++){
while(pos && !next[pos][s[i]-ch]) pos = fair[pos];
if(pos) pos = next[pos][s[i]-ch];
else pos = root[id];
ret += mark1[pos];
}
}
return ret;
}
void Unit(int u, int v){
mark[u] += mark[v];
for(int i = ; i < m; i++){
if(!next[u][i] || !next[v][i]) next[u][i] += next[v][i];
else Unit(next[u][i], next[v][i]);
}
}
}ac[];
char str[N];
int main(){
int n, k;
scanf("%d", &n);
while(n--){
scanf("%d%s", &k, str);
if(k <= ) ac[k-].Add(str, 'a');
else {
printf("%d\n", ac[].Query(str, 'a')-ac[].Query(str, 'a'));
fflush(stdout);
}
}
return ;
} AC自动机
模板汇总——AC自动机的更多相关文章
- 洛谷P3796 - 【模板】AC自动机(加强版)
原题链接 Description 模板题啦~ Code //[模板]AC自动机(加强版) #include <cstdio> #include <cstring> int co ...
- P3796 【模板】AC自动机(加强版)
P3796 [模板]AC自动机(加强版) https://www.luogu.org/problemnew/show/P3796 题目描述 有NN个由小写字母组成的模式串以及一个文本串TT.每个模式串 ...
- 模板】AC自动机(简单版)
模板]AC自动机(简单版) https://www.luogu.org/problemnew/show/P3808 这是一道简单的AC自动机模板题. 用于检测正确性以及算法常数. 为了防止卡OJ,在保 ...
- 【学时总结&模板时间】◆学时·10 & 模板·3◆ AC自动机
◇学时·10 & 模板·3◇ AC自动机 跟着高中上课……讲AC自动机的扩展运用.然而连KMP.trie字典树都不怎么会用的我一脸懵逼<(_ _)> 花一上午自学了一下AC自动机 ...
- 模板—字符串—AC自动机(多模式串,单文本串)
模板—字符串—AC自动机(多模式串,单文本串) Code: #include <queue> #include <cstdio> #include <cstring> ...
- 【题解】P3796【模板】AC自动机(加强版)
[题解]P3796 [模板]AC自动机(加强版) 记录当前\(cnt\)是第几个"星".记录第几个串是对应着第几个星. 这里补充一点对于\(AC\)自动机的理解.可能一直有个问题我 ...
- 「LuoguP3796」 【模板】AC自动机(加强版)
题目描述 有N个由小写字母组成的模式串以及一个文本串T.每个模式串可能会在文本串中出现多次.你需要找出哪些模式串在文本串T中出现的次数最多. 输入输出格式 输入格式: 输入含多组数据. 每组数据的第一 ...
- 洛谷P3808 【模板】AC自动机(简单版)
题目背景 这是一道简单的AC自动机模板题. 用于检测正确性以及算法常数. 为了防止卡OJ,在保证正确的基础上只有两组数据,请不要恶意提交. 管理员提示:本题数据内有重复的单词,且重复单词应该计算多次, ...
- 【刷题】洛谷 P3808 【模板】AC自动机(简单版)
题目背景 这是一道简单的AC自动机模板题. 用于检测正确性以及算法常数. 为了防止卡OJ,在保证正确的基础上只有两组数据,请不要恶意提交. 管理员提示:本题数据内有重复的单词,且重复单词应该计算多次, ...
随机推荐
- vue 移动端/PC常见问题及解决方法
一.判断手机/PC浏览器语言 navigator.language // 返回语言代码 语言代码文档: http://www.lingoes.cn/zh/translator/langcode.htm ...
- 解决VS2008,重新生成解决方案,很慢
正所谓:“工欲善其事,必先利其器“.我也算是深受其害了,特把经验分享出来为大伙分忧! 在刚来公司的时候,使用的公司提供的VS2008作为开发工具,有一个非常让人不爽的问题,就是在重新编译代码(重新生成 ...
- tomcat和weblogic发布时,jar包内资源文件的读取路径问题
问题场景: 本地使用的是tomcat作为发布容器,应用启动后一切正常: 发布测试环境服务器使用weblogic作为发布容器,发布后File类读取文件无法找到文件(路径错误). 问题原因: tomcat ...
- 使用DOM4J 对xml解析操作
参考自:https://blog.csdn.net/redarmy_chen/article/details/12969219 dom4j是一个Java的XML API,类似于jdom,用来读写XML ...
- socket基于TCP(粘包现象和处理)
目录 6socket套接字 7基于TCP协议的socket简单的网络通信 AF_UNIX AF_INET(应用最广泛的一个) 报错类型 单一 链接+循环通信 远程命令 9.tcp 实例:远程执行命令 ...
- webpack4 前端框架基础配置实例-解决css分离图片路径问题
1.安装nodejs 2. 需要全局和项目安装webpack和webpack-dev-server npm install webpack webpack-dev-server -g npm inst ...
- 从零写一个编译器(十一):代码生成之Java字节码基础
项目的完整代码在 C2j-Compiler 前言 第十一篇,终于要进入代码生成部分了,但是但是在此之前,因为我们要做的是C语言到字节码的编译,所以自然要了解一些字节码,但是由于C语言比较简单,所以只需 ...
- 深入理解Mysql索引底层数据结构与算法
索引是帮助MySQL高效获取数据的排好序的数据结构 索引数据结构对比 二叉树 左边子节点的数据小于父节点数据,右边子节点的数据大于父节点数据. 如果col2是索引,查找索引为89的行元素,那么只需要查 ...
- 淘宝自动登录2.0,新增Cookies序列化
前段时间时间为大家讲解了如何使用requests库模拟登录淘宝,而今天我们将对该功能进行丰富.所以我们把之前的那个版本定为1.0,而今天修改的版本定为2.0.版本的地跌意味着功能的升级,那今天的2.0 ...
- 轻松pick移动开发第二篇,rem布局
一.为什么要使用rem布局 前面我写了flex布局的优点,分配伸缩盒容器中子盒子占的份数及排列方式,使其不受屏幕缩放的影响,使布局变得简单.然而,在有些时候,不可避免要给盒子设置高度的值,怎么让高度也 ...