GalaxyOJ-786 (AC自动机)
来源:互联网 发布:os x软件推荐 编辑:程序博客网 时间:2024/06/10 20:04
题目
Problem Description
这是一道很容易ac的简单的字符串题。
给你n个字符串,这个字符串是由小写字母组成。
有q个询问,每次给出x和y。
找到第x个字符串和第y个字符串的连续公共子串同时也是某个字符串的前缀的串(某个字符串是指第一个字符串到第n个字符串的任意一个,包含第x个和第y个)。问这样的串的最长长度是多少。Input
第一行一个数字n,表示字符串的个数
接下来的n行给出了这n个字符串。
接下来是一个整数q,表示询问个数
接下来的q行,一行有两个整数表示x和y20%的数据,n,字母总个数<=10
50%的数据,n,字母总个数<=100
100%的数据,n,字母总个数<=100000,q<=100Output
共q行,一行一个整数,表示第q个询问的答案
Sample Input
3
aaa
baaa
caaa
2
2 3
1 2Sample Output
3
3
分析
- 题目就是给 n 个字符串,每次询问给你其中两个两个,问他们两个中是这 n 个串中某个的前缀的的公共连续子串最长可以是多少。
- 看看题目写着“容易ac的题”,结果是道 AC自动机 的题 罒w罒。
- 首先把这 n 个串建成一个字典树,然后像 AC自动机 那样弄好 fail 指针,然后对于每个询问的两个串,从每个串第一个字符开始都这样操作一遍——
- 一直跳fail,直到它到了根节点
- 把路径上的点打上标记
- 这样下来,每个打上标记的点所代表的字符串肯定是 n 个串中某个的前缀,且是当前串的一个连续子串。
- 然后把两个串打的标记记下来,比较一下那些两个串都打过标记的点,他们代表着符合要求(但不一定是最长)的串,然后拿出长度最长(即在字典树中深度最深)的那个长度即可。
程序
#include <cstdio>#include <string>#include <iostream>#include <algorithm>#define X (ch[i][j]-'a')#define son(x) (to[fa][x])using namespace std;string ch[100001];int n,i,j,k,g,xx,yy,ans,L,Q,fa,f[2][105][100005];int head[100005],to[100005][30],cnt;int l,r,dep[100005],q[100005],fail[100005];void get_fail(){ for (i=q[l=r=0]=0; l<=r; i=q[++l]) for (j=0; j<26; j++) if (to[i][j]){ q[++r]=to[i][j]; for (fa=fail[i]; fa && !son(j); fa=fail[fa]); if (i>0 && son(j)) fail[to[i][j]]=son(j); } else to[i][j]=to[fail[i]][j];}void que(string x,int m){ for (k=to[0][x[j=0]-'a'],L=x.length(); j<L; k=to[k][x[++j]-'a']){ for (g=k; g; g=fail[g]){ if (f[m^1][Q][g]){ans=max(dep[g],ans); break;} if (f[m][Q][g]) break; f[m][Q][g]=1; } }}int main(){ scanf("%d",&n); for (i=1; i<=n; i++){ cin >>ch[i]; for (j=0,k=0,L=ch[i].length(); j<L; dep[k]=++j) k=(to[k][X] ? to[k][X] : (to[k][X]=++cnt)); } get_fail(); for (scanf("%d",&Q); Q--; ans=0){ scanf("%d%d",&xx,&yy); que(ch[xx],0); que(ch[yy],1); printf("%d\n",ans); }}
提示
- 我开始用的是字符数组(平常我也是用字符数组的),可是交上去发现居然 RE ,原来是题目说 n,总字符数 都可以为 100000,然后极限数据就是全是一个字符的串,后来无奈用了 string ,然后就过了。
阅读全文
0 0
- GalaxyOJ-786 (AC自动机)
- AC自动机...
- AC自动机
- AC 自动机
- AC自动机
- AC自动机
- ac自动机
- ac自动机
- AC自动机
- AC自动机
- AC自动机
- AC自动机
- AC自动机
- AC 自动机
- ac自动机
- AC自动机
- AC自动机
- AC自动机
- C# 虚拟方法
- Java实现文件上传
- Java 8 最佳技巧
- HDU-6152Friend-Graph
- 当彗星划过天空,那好像梦幻一般的景色,真是无与伦比,美到极致,只能让人一味眺望着那无法言喻的美。
- GalaxyOJ-786 (AC自动机)
- React Native中状态栏设置StatusBar
- python爬虫学习第二十七天(补昨天)
- Java 9 中的 9 个新特性
- 当谈论ARM架构时,至少该谈点什么?
- AngularJS 参考手册-只供参考学习
- mockito单元测试demo
- 南京答辩心得
- c++的发展方向