一些AC自动机的(水)题
推荐博客:https://blog.csdn.net/bestsort/article/details/82947639
题目总结:
洛谷P3808 【模板】AC自动机(简单版)
洛谷P3796 【模板】AC自动机(加强版)
洛谷P5357 【模板】AC自动机(二次加强版)
HDU2222
正题:
洛谷P3808 【模板】AC自动机(简单版)
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<queue>
#include<stack>
#include<cmath>
#include<cstdlib>using namespace std;
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define inf 0x3f3f3f3f
int dis[500005][26],ida,fail[500005],cnt[500005];void insert(string s)
{int p = 0,len = s.size();for(int i = 0;i < len;i++){int u = s[i] - 'a';if(!dis[p][u]) dis[p][u] = ++ida;p = dis[p][u];}cnt[p]++;
}void getfail()
{queue<int> q;for(int i = 0;i < 26;i++) {if(dis[0][i]) {fail[dis[0][i]] = 0;q.push(dis[0][i]);}}while(!q.empty()){int u = q.front();q.pop();for(int i = 0;i < 26;i++){if(dis[u][i]){fail[dis[u][i]] = dis[fail[u]][i];q.push(dis[u][i]);}else dis[u][i] = dis[fail[u]][i];}}
}int query(string s)
{ int u = 0,ans = 0;int len = s.size();for(int i = 0;i < len;i++){u = dis[u][s[i] - 'a'];for(int j = u;u && cnt[j] != -1;j = fail[j]){ans += cnt[j];cnt[j] = -1;}}return ans;
}int main()
{ int n;string t,s;IOS;while(cin>>n){ida = 0;memset(cnt,0,sizeof(cnt));memset(fail,0,sizeof(fail));memset(dis,0,sizeof(dis));for(int i = 1;i <= n;i++){cin>>t;insert(t);}getfail();cin>>s;cout<<query(s)<<endl;}
return 0;
}
洛谷P3796 【模板】AC自动机(加强版)
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<queue>
#include<stack>
#include<cmath>
#include<cstdlib>using namespace std;
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define inf 0x3f3f3f3f
int dis[500005][26],ida,fail[500005],cnt[500005],vis[500005];void insert(string s,int num)
{int p = 0,len = s.size();for(int i = 0;i < len;i++){int u = s[i] - 'a';if(!dis[p][u]) dis[p][u] = ++ida;p = dis[p][u];}cnt[p] = num;
}void getfail()
{queue<int> q;for(int i = 0;i < 26;i++) {if(dis[0][i]) {fail[dis[0][i]] = 0;q.push(dis[0][i]);}}while(!q.empty()){int u = q.front();q.pop();for(int i = 0;i < 26;i++){if(dis[u][i]){fail[dis[u][i]] = dis[fail[u]][i];q.push(dis[u][i]);}else dis[u][i] = dis[fail[u]][i];}}
}void query(string s)
{ int u = 0,ans = 0;int len = s.size();for(int i = 0;i < len;i++){u = dis[u][s[i] - 'a'];for(int j = u;j;j = fail[j]){vis[cnt[j]] ++;}}
}int main()
{ int n;string t[50005],s;IOS;while(cin>>n&&n){ida = 0;memset(cnt,0,sizeof(cnt));memset(fail,0,sizeof(fail));memset(dis,0,sizeof(dis));for(int i = 1;i <= n;i++){cin>>t[i];vis[i] = 0;insert(t[i],i);}getfail();cin>>s;query(s);int ans = 0;for(int i = 1;i <= n;i++) ans = max(ans,vis[i]);cout<<ans<<endl;for(int i = 1;i <= n;i++){if(vis[i] == ans) cout<<t[i]<<endl;}}
return 0;
}
洛谷P5357 【模板】AC自动机(二次加强版)
推荐博客:https://www.luogu.com.cn/blog/juruohyfhaha/solution-p5357
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<queue>
#include<stack>
#include<cmath>
#include<cstdlib>using namespace std;
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define inf 0x3f3f3f3f
int n,cnt,in[500005],vis[500005],ans,map[500005];
struct mmp
{int son[26],fail,flag,ans;
}trie[500005];
queue<int>q;
void insert(string s,int num)
{int u = 0,len = s.size();for(int i = 0;i < len;i++){int v = s[i] - 'a';if(!trie[u].son[v]) trie[u].son[v] = ++cnt;u = trie[u].son[v];}if(!trie[u].flag) trie[u].flag = num;map[num] = trie[u].flag;
}
void getfail()
{for(int i = 0;i < 26;i++)if(trie[0].son[i]) {q.push(trie[0].son[i]);trie[trie[0].son[i]].fail = 0;}while(!q.empty()){int u = q.front();q.pop();int Fail = trie[u].fail;for(int i = 0;i < 26;i++){int v = trie[u].son[i];if(v){q.push(v);trie[v].fail = trie[Fail].son[i];in[trie[v].fail] ++;}else trie[u].son[i] = trie[Fail].son[i];}}
}
void query(string s)
{int u = 0,len = s.size();for(int i = 0;i < len;i++){u = trie[u].son[s[i] - 'a'];trie[u].ans++;}
}
void topu()
{for(int i = 0;i <= cnt;i++)if(!in[i]) q.push(i);while(!q.empty()){int u = q.front();q.pop();vis[trie[u].flag] = trie[u].ans;int v = trie[u].fail;in[v]--;trie[v].ans += trie[u].ans;if(in[v] == 0) q.push(v);}
}
int main()
{IOS;string s,t;while(cin>>n){memset(trie,0,sizeof(trie));memset(map,0,sizeof(map));memset(vis,0,sizeof(vis));cnt = 0;for(int i = 1;i <= n;i++){cin>>t;insert(t,i);}getfail();cin>>s;query(s);topu();for(int i = 1;i <= n;i++) cout<<vis[map[i]]<<endl;}
return 0;
}
HDU2222
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<queue>
#include<stack>
#include<cmath>
#include<cstdlib>using namespace std;
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define inf 0x3f3f3f3f
int n,cnt,in[500005],ans;
char s[1000005],t[55];
struct mmp
{int son[26],fail,flag,ans;
}trie[500005];
queue<int>q;
void insert()
{int u = 0,len = strlen(t);for(int i = 0;i < len;i++){int v = t[i] - 'a';if(!trie[u].son[v]) trie[u].son[v] = ++cnt;u = trie[u].son[v];}trie[u].flag ++;
}
void getfail()
{for(int i = 0;i < 26;i++)if(trie[0].son[i]) {q.push(trie[0].son[i]);trie[trie[0].son[i]].fail = 0;}while(!q.empty()){int u = q.front();q.pop();int Fail = trie[u].fail;for(int i = 0;i < 26;i++){int v = trie[u].son[i];if(v){q.push(v);trie[v].fail = trie[Fail].son[i];in[trie[v].fail] ++;}else trie[u].son[i] = trie[Fail].son[i];}}
}
void query()
{int u = 0,len = strlen(s);for(int i = 0;i < len;i++){u = trie[u].son[s[i] - 'a'];trie[u].ans++;}
}
void topu()
{for(int i = 0;i <= cnt;i++)if(!in[i]) q.push(i);while(!q.empty()){int u = q.front();q.pop();int v = trie[u].fail;in[v]--;trie[v].ans += trie[u].ans;if(trie[u].flag && trie[u].ans) {ans += trie[u].flag;trie[u].ans = 0;}if(in[v] == 0) q.push(v);}
}
int main()
{int T;scanf("%d",&T);while(T--){scanf("%d",&n);memset(trie,0,sizeof(trie));cnt = ans = 0;for(int i = 1;i <= n;i++){scanf("%s",&t);insert();}getfail();scanf("%s",s);query();topu();printf("%d\n",ans);}
return 0;
}
一些AC自动机的(水)题相关推荐
- AC自动机-HDU2222-模板题
http://acm.hdu.edu.cn/showproblem.php?pid=2222 一个AC自动机的模板题.用的kuangbin的模板,静态建Trie树.可能遇到MLE的情况要转动态建树. ...
- woj1572 Cyy and Fzz KMP / AC自动机 + DP
题目:http://acm.whu.edu.cn/land/problem/detail?problem_id=1572 题意: 有n个目标串,长度均小于15,(n<=8),现在随机写一个长度 ...
- HDU2222 Keywords Search(AC自动机模板)
AC自动机是一种多模式匹配的算法.大概过程如下: 首先所有模式串构造一棵Trie树,Trie树上的每个非根结点都代表一个从根出发到该点路径的字符串. 然后每个结点都计算出其fail指针的值,这个fai ...
- CodeForces - 1437G Death DBMS(AC自动机fail树上树链剖分建线段树/暴跳fail)
题目链接:点击查看 题目大意:给出 n 个模式串,每个模式串初始时的权值为 0,然后有 m 次操作: 1 i x:将第 i 个模式串的权值修改为 x 2 s:给出一个字符串 s,询问字符串 s 作为主 ...
- HDU - 2222 Keywords Search(AC自动机)
题目链接:点击查看 题目大意:给出n个长度不超过50的模式串,再给出一个长度不超过1e6的主串,问模式串在主串中出现过多少次 题目分析:一开始我以为是求n次KMP,后来才知道这样做的时间复杂度是O(L ...
- 2017西安交大ACM小学期 文本查找[AC自动机]
文本查找 发布时间: 2017年7月5日 00:10 最后更新: 2017年7月5日 13:47 时间限制: 1500ms 内存限制: 128M 描述 给定m种两两不同的关键词,并给定一段 ...
- 【HDU2896】病毒侵袭——ac自动机
网上很多代码都略显繁琐,看了一下yy dalao的代码感觉很好,但他懒得打题解(好吧我也是 以0为根节点的话,我把yy的一段代码删了改用fail[c]=x==0?0:ch[fail[x]][i];来实 ...
- AC自动机 HDU 2222
AC自动机分为三部分: 1.构造字典树 2.构找失败指针 3.匹配 解决的问题: 如给你n个单词,然后一篇问章,问你这篇文章中单词出现了多少次? View Code /* 程序说明:多模式串匹配的AC ...
- 【谈谈知识点】AC自动机
前言 一言不合就开坑,说的就是我~ 之前觉得这东西挺难,然后某天早上花了一个半小时就学会了-- P.S:如果你诚心诚意的想学会AC自动机,一定要先去看懂KMP和Trie. 而且一定要好好理解KMP的n ...
- HUD2222 Keywords Serch AC自动机
传送门 显然这是一道AC自动机的模板题 但是还有一些地方需要注意: 1.多组数据要每次清空数组 2.关键字重复要累加,但是文本重复不能累加,可以打标记解决 #include<cstdio> ...
最新文章
- WWDC 2018:iOS 12 通知的新特性
- 服务器2012r2系统远程登陆,服务器2012r2系统远程登陆
- 运营必备,系统运营知识有这篇就够了!
- BuddyPress安装指南
- SpringCloud 从菜鸟到大牛之七 服务网关 Zuul API网关等等
- 论文笔记 - 《Very Deep Convolutional Networks For Large-Scale Image Recognition》 精典
- Array和ArrayList的区别与联系
- 计算机控制面板设置命令,电脑的控制面板在哪打开,分享四种打开方法
- 报纸样式网页html css,报纸杂志HTML模板
- Web并发页面访问量统计实现
- 微信小程序原生的下拉框组件
- Win10 启动模拟器
- Intellij IDEA 查看所有断点
- 互联网日报 | 滴滴出租车上线“作弊举报”功能;蚂蚁集团进入上市辅导期;百度App日活达2.04亿...
- A Database Error Occurred Error Number:0
- 上dj是什么意思_DJ是什么意思?
- Abaqus 2016基础操作到高级接触分析视频教程
- Android网络请求
- 计算机管理员限制会怎么样,电脑被管理员限制登录微信了怎么办
- Wacom对3DCOAT的设置