hdu 6138 Fleet of the Eternal Throne(AC自动机)
来源:互联网 发布:惠州网络推广公司 编辑:程序博客网 时间:2024/06/08 10:40
http://acm.hdu.edu.cn/showproblem.php?pid=6138
题目大意:给出n个字符串后,会有q个询问,每个询问会输入两个数,记为x,y。然后要求的是,x,y的 最长公共子串,而且这个最长公共子串要是n个字符串中某个字符串的前缀。输出这个串的长度。
解题思路:这题的题意很明确,首先我们要求出x,y串的公共子串,然后要在n个字符串中出现过。这样就可以用的AC自动机。AC自动机原来是用来多模式匹配的,原来每个节点维护的值有一个标记是否是一个完整的字符串,然而由于该题是要前缀长度,我们就要队节点维护的值有所改进,每个节点维护其所代表的前缀的长度即可。这样的话,我们可以用这n个字符串构建字典树,然后通过BFS找到每个节点对应的fail指针,接下来,由于我们要找的是第x个字符串和第y个字符串的最长公共字串长度,且该字串是n个字符串中某个字符串的前缀。因此我们需要用第x个字符串和第y个字符串在字典树上进行一个匹配。当第x个字符串去匹配的时候,我们要做的就是把所有在匹配时经过的节点都标记一下。代表这些节点到字典树的根所代的字符串既是某个字符串的前缀,还在第x个字符串中。同理我们让第y个字符串在按相同的方法跑一遍AC自动机,有所不同的是,第一个串跑完之后已经留下标记,我们可以在第2个串跑的时候,直接通过检测标记来确定某个节点所代表的字符串是不是x,y的共同子串。然后边检测边求解答案就可以了。
#include <bits/stdc++.h>using namespace std;struct Trie{ int len,flag; Trie *fail; Trie *child[26]; Trie() { flag = 0; len = 0; fail = NULL; for(int i=0; i<26; i++) child[i] = NULL; }};Trie *root,*current,*temp;string str[100005];int ans;void _insert(string s){ current = root; for(int i=0; i<s.length(); i++) { int index = s[i] - 'a'; if(current->child[index] == NULL) { temp = new Trie; temp->len = current->len+1; current->child[index] = temp; } current = current->child[index]; // (current->len)++; }}void Find_fail(){ queue<Trie*> Q; Q.push(root); while(!Q.empty()) { current = Q.front(); Q.pop(); for(int i=0; i<26; i++) { if(current->child[i]!=NULL) { if(current==root) current->child[i]->fail = root; else { Trie *p = current->fail; while(p) { if(p->child[i]) { current->child[i]->fail = p->child[i]; break; } p=p->fail; } if(p==NULL) current->child[i]->fail = root; } Q.push(current->child[i]); } } }}void _search(string s,int f){ current = root; for(int i=0; i<s.length(); i++) { int index = s[i]-'a'; while(!current->child[index]&¤t!=root) current = current->fail; current = current->child[index]; if(!current) current = root; temp = current; while(temp!=root) { temp->flag = f; temp = temp->fail; } }}void AC_authomation(string s,int f){ current = root; for(int i=0; i<s.length(); i++) { int index = s[i]-'a'; while(!current->child[index]&¤t!=root) current = current->fail; current = current->child[index]; if(!current) current = root; temp = current; while(temp!=root) { if(temp->flag == f) { ans = max(temp->len,ans); } temp = temp->fail; } }}int main(){ int T; scanf("%d",&T); while(T--) { int n,q,x,y; root = new Trie; scanf("%d",&n); for(int i=1; i<=n; i++) { cin>>str[i]; _insert(str[i]); } Find_fail(); scanf("%d",&q); for(int i=1; i<=q; i++) { ans = 0; scanf("%d %d",&x,&y); _search(str[x],i); AC_authomation(str[y],i); printf("%d\n",ans); } } return 0;}
阅读全文
0 0
- HDU 6138 Fleet of the Eternal Throne ( AC自动机)
- hdu 6138 Fleet of the Eternal Throne(AC自动机)
- HDU 6138 Fleet of the Eternal Throne(AC自动机)
- hdu 6138 Fleet of the Eternal Throne (ac自动机)
- HDU 6138 Fleet of the Eternal Throne [AC自动机]
- HDU 6138 Fleet of the Eternal Throne (AC自动机)
- HDU 6138 Fleet of the Eternal Throne AC自动机
- HDU 6138 2017多校第八场1006 Fleet of the Eternal Throne :AC自动机
- HDU 6138 Fleet of the Eternal Throne AC自动机||后缀数组
- HDU 6138 Fleet of the Eternal Throne 多校#8 AC自动机
- HDU 6138 Fleet of the Eternal Throne 多校#8 AC自动机
- HDU 6138 Fleet of the Eternal Throne
- hdu 6138 Fleet of the Eternal Throne
- HDU 6138 Fleet of the Eternal Throne
- hdu6138 Fleet of the Eternal Throne AC自动机
- HDU 6138 Fleet of the Eternal Throne (2017多校8
- HDU 6138 Fleet of the Eternal Throne (2017多校8
- HDU_6138 Fleet of the Eternal Throne 【AC自动机&&思维】【静态数组】
- java面试题和答案(2)
- DeepLearning(花书)第二章主要内容(7-12节)
- vs qt 环境配置
- 56. Merge Intervals
- 图像分割结果的评估
- hdu 6138 Fleet of the Eternal Throne(AC自动机)
- 关于zookeeper第三方客户端zkclient的使用说明
- hdu 6118 度度熊的交易计划【费用流模板题】
- 【JavaScript 基础】01 基础语法
- 第十九天
- C 头文件
- 跟上 Java 8 – 你忽略了的新特性
- Servlet常用知识点
- 腾讯 云通信 如何启动Demo