HDU 6138 AC自动机
来源:互联网 发布:spss筛选数据统计 编辑:程序博客网 时间:2024/06/03 20:09
题意:
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6138
给出n个字符串,m个询问,询问x和y两个字符的最长公共子串的长度,而且要求这个子串为这n个字符串中任意一个(或多个)的前缀。
思路:
AC自动机。
每个节点end数组都保存当前节点到根节点的距离。将n个字符串保加入AC自动机。然后对x在自动机上跑一边标记节点,然后再对y跑一遍,遇到标记的节点就更新答案。注意每次还要再去除标记。
代码:
#include <bits/stdc++.h>using namespace std;typedef long long LL;const int INF = 0x3f3f3f3f;const LL MOD = 1e9 + 7;const int MAXN = 1e5 + 10;struct ACauto { int next[MAXN][26], fail[MAXN], end[MAXN], vis[MAXN]; int root, sz; int newnode() { for (int i = 0; i < 26; i++) next[sz][i] = -1; end[sz++] = 0; return sz - 1; } void init() { sz = 0; root = newnode(); } int idx(char c) { return c - 'a'; } void insert(char *buf) { int len = strlen(buf); int now = root; for (int i = 0; i < len; i++) { int id = idx(buf[i]); if (next[now][id] == -1) next[now][id] = newnode(); now = next[now][id]; end[now] = i + 1; vis[now] = false; } } void build() { queue <int> Q; fail[root] = root; for (int i = 0; i < 26; i++) { if (next[root][i] == -1) next[root][i] = root; else { fail[next[root][i]] = root; Q.push(next[root][i]); } } while (!Q.empty()) { int now = Q.front(); Q.pop(); for (int i = 0; i < 26; i++) { if (next[now][i] == -1) next[now][i] = next[fail[now]][i]; else { fail[next[now][i]] = next[fail[now]][i]; Q.push(next[now][i]); } } } } int query(char *s, int ls, char *t, int lt) { int now = root, res = 0; for (int i = 0; i < ls; i++) { int id = idx(s[i]); now = next[now][id]; int tmp = now; while (tmp != root) { vis[tmp] = true; tmp = fail[tmp]; } } now = root; for (int i = 0; i < lt; i++) { int id = idx(t[i]); now = next[now][id]; int tmp = now; while (tmp != root) { if (vis[tmp]) res = max(res, end[tmp]); tmp = fail[tmp]; } } now = root; for (int i = 0; i < ls; i++) { int id = idx(s[i]); now = next[now][id]; int tmp = now; while (tmp != root) { vis[tmp] = false; tmp = fail[tmp]; } } return res; }} ac;string s[MAXN];int len[MAXN];char s1[MAXN], s2[MAXN];int main() { //freopen("in.txt", "r", stdin); int T; scanf("%d", &T); while (T--) { int n, m; scanf("%d", &n); ac.init(); for (int i = 1; i <= n; i++) { cin >> s[i]; len[i] = s[i].length(); strcpy(s1, s[i].c_str()); ac.insert(s1); } ac.build(); /*for (int i = 0; i < ac.sz; i++) cout << i << " " << ac.end[i] << endl;*/ scanf("%d", &m); while (m--) { int x, y; scanf("%d%d", &x, &y); strcpy(s1, s[x].c_str()); strcpy(s2, s[y].c_str()); printf("%d\n", ac.query(s1, len[x], s2, len[y])); } } return 0;}
阅读全文
0 0
- HDU 6138 AC自动机
- hdu 6138 ac自动机
- HDU 6138 AC自动机
- AC自动机 hdu 2222
- HDU 2222(AC 自动机)
- hdu 2222 AC自动机
- hdu 3065(AC自动机)
- HDU 2222 AC自动机
- HDU 2896 AC自动机
- HDU 3065 AC自动机
- HDU 2896 AC自动机
- HDU-3695-ac自动机
- Hdu 2222 [AC自动机]
- hdu 2222 AC自动机 。。
- hdu 3695 ac自动机
- hdu 2896 ac自动机
- hdu 2222 AC自动机
- hdu 3065 AC自动机
- 关于部署好tomcat的环境下 jsp文件在eclipse中能运行,但是在浏览器打开时显示404错误的个人笔记
- window安装Python环境
- Spring 使用JDBC
- 数据结构-双向链表插入
- PAT_A 1059. Prime Factors (25)
- HDU 6138 AC自动机
- yii2.0 的安装
- 计算结构体的大小
- 【PAT】【Advanced Level】1057. Stack (30)
- OKHTTP3的简单使用,表单提交,json传递
- 阿里云服务器部署个人博客
- sublime执行出现编码错误
- Linux 使用selenium chrome实现爬虫的两个坑
- unrecognized Windows Sockets error: 10106: create