LA4670 AC自动机
来源:互联网 发布:log4j sql日志级别 编辑:程序博客网 时间:2024/06/15 20:51
分析:本题模板串多且长度短,文本串却很长,适合使用AC自动机。
一个容易忽略的地方是重复出现的模板,如果有模板重复,后一个子串会覆盖前一个子串。因此要建立一个字符串到编号的索引map<string,int>mp,每次初始化时候清空。
代码如下:
#include <cstring>#include <cstdio>#include <queue>#include <map>#include <string>using namespace std;const int sigma_size = 26;const int maxs = 150+10;const int maxn = 11000;map<string,int>mp;queue<int>que;int ch[maxn][sigma_size];int fail[maxn]; //fail函数int val[maxn]; //每个字符串的结尾结点都有一个非0的valint last[maxn]; //输出链表的下一个结点int cnt[maxs];char p[maxs][80];char text[1000000+10];int sz;int N;int idx(char c) { return c-'a';}//插入字符串,v必须非零void Insert(char *s, int v){ int u = 0, len = strlen(s); int c; for (int i=0; i<len; i++){ c = idx(s[i]); if (!ch[u][c]) { memset(ch[sz],0,sizeof(ch[sz])); val[sz] = 0; ch[u][c] = sz++; } u = ch[u][c]; } val[u] = v; mp[string(s)] = v;}void init(){ sz = 1; memset(ch[0],0,sizeof(ch[0])); memset(cnt,0,sizeof(cnt)); mp.clear(); for (int i=1; i<=N; i++) { scanf("%s",p[i]); Insert(p[i],i); }}void getfail(){ while(!que.empty()) que.pop(); fail[0] = 0; int u,r,v; for (int i=0; i<sigma_size; i++) { u = ch[0][i]; if (u) {fail[u] = 0; que.push(u); last[u] = 0;} } while (!que.empty()){ r = que.front(); que.pop(); for (int c=0; c<sigma_size; c++){ u = ch[r][c]; if (!u) continue; que.push(u); v = fail[r]; while (v && !ch[v][c]) v = fail[v]; fail[u] = ch[v][c]; last[u] = val[fail[u]]? fail[u]:last[fail[u]]; } }}void Print(int x){ if (x){ cnt[val[x]]++; Print(last[x]); }}void Find(char *T){ int len = strlen(T); int j = 0,c; for (int i=0; i<len; i++){ c = idx(T[i]); while (j && !ch[j][c]) j = fail[j]; j = ch[j][c]; if (val[j]) Print(j); else if (last[j]) Print(last[j]); }}int MAX(int x, int y){return x>y?x:y;}int main(){ while (scanf("%d",&N) && N){ init(); getfail(); scanf("%s",text); Find(text); int best = -1; for (int i=1; i<=N; i++) best = MAX(best,cnt[i]); printf("%d\n",best); for (int i=1; i<=N; i++) if (best==cnt[mp[string(p[i])]]) printf("%s\n",p[i]); } return 0;}
阅读全文
0 0
- AC自动机 LA4670
- AC自动机模板 LA4670
- LA4670 AC自动机
- LA4670 AC自动机模版题
- LA4670 Dominating Patterns[AC自动机]
- LA4670 Dominating Patterns(AC自动机)
- UVA 1449 Dominating Patterns (LA4670) 出现次数最多的子串 ac自动机
- AC自动机模板 LA4670 Dominating Patterns 出现次数最多的字串 BNUOJ11552 UVA1449
- la4670
- AC自动机...
- AC自动机
- AC 自动机
- AC自动机
- AC自动机
- ac自动机
- ac自动机
- AC自动机
- AC自动机
- IDENTITY_INSERT
- 浅谈JavaScript异步加载的三种方式——async和defer、动态创建script
- Single Image Haze Removal(图像去雾)-CVPR’09 Best Paper
- 洛谷U14200 Changing 题解 【杨辉三角】
- 作业
- LA4670 AC自动机
- Mysql查询
- 计算机的色彩表示——十六进制颜色码
- Junit4初次接触
- HTLM元素
- 第8周项目3- 对称矩阵压缩存储的实现与应用(3)
- uva260
- Andriodjie——RecyclerView点击查看商品详情
- 用WinRAR将exe与所依赖的dll与资源打包成一个exe