[luogu2292][L语言]
程序员文章站
2024-01-13 13:14:22
思路
这道题我用的是AC自动机的做法。
先把子串挂到tried树上,在单词结尾打标记的时候,标记的是当前单词的长度。然后去上面查询母串的时候,每查询到一个单词,就建立一条 ......
题目链接
思路
这道题我用的是ac自动机的做法。
先把子串挂到trie树上,在单词结尾打标记的时候,标记的是当前单词的长度。然后去上面查询母串的时候,每查询到一个单词,就建立一条线段,这条线段的结尾位置是母串当前的位置,开始位置就是用当前位置减去这个单词的长度。
然后只要去判断,选出一些线段,使得这些线段紧挨着(既不相互覆盖,中间也不遗漏)从母串开始位置铺,能铺到的最远的地方。所以只需要一遍bfs就行了。
代码
/* * @author: wxyww * @date: 2018-12-17 08:38:38 * @last modified time: 2018-12-17 09:09:28 */ #include<cstdio> #include<iostream> #include<cstdlib> #include<cmath> #include<ctime> #include<bitset> #include<cstring> #include<queue> using namespace std; typedef long long ll; const int n = 2000000 + 100; ll read() { ll x=0,f=1;char c=getchar(); while(c<'0'||c>'9') { if(c=='-') f=-1; c=getchar(); } while(c>='0'&&c<='9') { x=x*10+c-'0'; c=getchar(); } return x*f; } int trie[1000][30],end[1000]; char s[30]; int tot; void insert() { int len = strlen(s + 1); int now = 0; for(int i = 1;i <= len;++i) { int k = s[i] - 'a'; if(!trie[now][k]) trie[now][k] = ++tot; now = trie[now][k]; } end[now] = len; } struct node { int l,r; }e[n]; int ejs; int fail[n]; char s[n]; queue<int>q; void build() { for(int i = 0;i < 26;++i) if(trie[0][i]) q.push(trie[0][i]); while(!q.empty()) { int u = q.front();q.pop(); for(int i = 0;i < 26;++i) { if(trie[u][i]) fail[trie[u][i]] = trie[fail[u]][i],q.push(trie[u][i]); else trie[u][i] = trie[fail[u]][i]; } } } vector<int>v[n]; void work() { int len = strlen(s + 1); ejs = 0;int now = 0; for(int i = 1;i <= len;++i) { now = trie[now][s[i] - 'a']; for(int j = now;j;j = fail[j]) { if(end[j]) e[++ejs].l = i - end[j] + 1,e[ejs].r = i; } } } int vis[n]; void bfs() { q.push(1); int ans = 0; for(int i = 1;i <= ejs;++i) v[e[i].l].push_back(i); memset(vis,0,sizeof(vis)); while(!q.empty()) { int l = q.front();q.pop(); int k = v[l].size(); for(int i = 0;i < k;++i) { int z = v[l][i]; if(vis[z]) continue; vis[z] = 1; q.push(e[z].r + 1); ans = max(ans,e[z].r); } } printf("%d\n",ans); int len = strlen(s + 1); for(int i = 1;i <= len;++i) v[i].clear(); } int main() { int n = read(),m = read(); for(int i = 1;i <= n;++i) { scanf("%s",s + 1); insert(); } build(); for(int i = 1;i <= m;++i) { scanf("%s",s + 1); work(); bfs(); } return 0; }
上一篇: php入门级书籍?
下一篇: QT TabBar无法使用怎么办
推荐阅读
-
[luogu2292][L语言]
-
HTML5 或者JS可以获取移动设备信息吗?或者其他非开发语言的方法?
-
InfoQ刚发表一篇论文《半静态语言–原理和价值分析》
-
python中 “与,或,异或”与C语言的不同
-
《疯狂Java讲义》读书笔记 第一章Java语言概述与开发环境
-
InfoQ刚发表一篇论文《半静态语言–原理和价值分析》
-
网站开发中PHP语言优缺点
-
ASP.NET MVC下使用AngularJs语言(九):日期时间处理与显示
-
现下想做一个信息发布网站,主要架构是中国行政区域,省,市.用什么语言或者技术最好
-
学习数据结构、图形学、系统编程、网络编程,哪门语言可以同时涵盖它们又能快速实现想法呢?