UVA 10679 I Love Strings
题目大意
给定文本串$S$和若干模式串$\{T\}$, 对每个模式串$T$, 询问$T$是否为$S$的子串.
Solution
裸的AC自动机, 也可以用后缀数组做.
P.S. 这题数据很弱, 朴素的字符串匹配也能过.
Pitfalls
模式串有重复的. 这样, 在建TRIE时就不能直接对每个模式串对应的节点 (尾节点) 标记上模式串的序号, 否则对于重复出现的模式串, 最后一次出现的那个会把在它之前的那些覆盖掉.
正确的做法是, 对于每个尾节点作唯一标号. 另外维护一个表$idx[]$, $idx[i]$表示第$i$个模式串的尾节点的标号.
另外要注意AC自动机的某些易错的实现细节, 代码注释有提及.
Implementation
注释比较详细, 可作为模板.
#include <bits/stdc++.h>
using namespace std; const int N{<<}, M{<<}; bool res[M];
int idx[M];
char s[N], t[M];
int ch[N][], id[N], fail[N], last[N]; int get_id(char ch){
return islower(ch)?ch-'a':ch-'A'+;
} queue<int> que; int main(){
// cout<<int('a')<<' '<<int('z')<<' '<<int('A')<<' '<<int('Z')<<endl;
int T;
for(cin>>T; T--; ){
int q;
scanf("%s%d", s, &q);
int tail=; memset(res, false, sizeof(res)); //error-prone memset(ch[tail], , sizeof(ch[tail]));
tail++; for(int i=; i<=q; i++){
scanf("%s", t);
int u=;
for(int j=; t[j]; j++){
int &v=ch[u][get_id(t[j])];
if(!v){
v=tail++;
memset(ch[v], , sizeof(ch[v]));
id[v]=;
}
u=v;
}
if(!id[u]) id[u]=i; //error-prone: possibly duplicate patterns
idx[i]=id[u];
} for(int i=; i<; i++){
int u=ch[][i];
if(u){
que.push(u);
fail[u]=last[u]=; //error-prone, must be initialized!!
}
} for(; que.size(); ){
int u=que.front();
que.pop();
for(int i=; i<; i++){
//!view a variable (object) as an entity
int &v=ch[u][i];
if(v){ //v is a new node, construct a new node of AC automata
que.push(v);
//no need to init. last[] and fail[], as they are is induced.
fail[v]=ch[fail[u]][i];
last[v]=id[fail[v]]?fail[v]:last[fail[v]];
}
else{ //the expected node v does not exist
v=ch[fail[u]][i];
}
}
} for(int i=, u=; s[i]; i++){
u=ch[u][get_id(s[i])];
res[id[u]]=true;
for(int v=last[u]; v; res[id[v]]=true, v=last[v]); //error-prone
} for(int i=; i<=q; i++)
puts(res[idx[i]]?"y":"n"); }
}
UPD
上面代码中第76行
for(int v=last[u]; v; res[id[v]]=true, v=last[v]);
可优化为
for(int v=last[u]; v && !res[id[v]]; res[id[v]]=true, v=last[v]);
这样可保证每个单词节点(dictionary node)通过last指针(dictionary suffix link) 的访问次数为至多为1 ,从而提高时间效率。
上穷碧落下黄泉.
UVA 10679 I Love Strings的更多相关文章
- UVA 10679 I love Strings!!!(AC自己主动机)
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&p ...
- UVa OJ 455 Periodic Strings
Periodic Strings A character string is said to have period k if it can be formed by concatenating ...
- lightoj 1052 - String Growth & uva 12045 - Fun with Strings 矩阵
思路:很容易发现规律,数列和Fib数列一样的. 记开始的时候啊a的个数为Y,b的个数为X.建立矩阵. 代码如下: #include<iostream> #include<cstdio ...
- 【习题 3-4 UVA - 455】Periodic Strings
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 枚举 [代码] #include <bits/stdc++.h> using namespace std; const ...
- UVa 455 - Periodic Strings解题报告
UVa OJ 455 Periodic Strings A character string is said to have period k if it can be formed by conca ...
- 一位学长的ACM总结(感触颇深)
发信人: fennec (fennec), 信区: Algorithm 标 题: acm 总结 by fennec 发信站: 吉林大学牡丹园站 (Wed Dec 8 16:27:55 2004) AC ...
- UVA.455 Periodic Strings(字符串的最小周期)
Periodic Strings 模板 题意分析 判断字符串的最小周期 代码总览 /* Title:UVA.455 Author:pengwill Date:2016-12-16 */ #includ ...
- uva 11081 - Strings(LCS)
题目链接:11081 - Strings 题目大意:给出三个字符串,从分别从第一个字符串和第二个字符串中挑选子串a,b,用a和b组成第三个字符串,问可组成的子串有多少种. 解题思路:说起来惭愧啊,题目 ...
- UVA - 10298 Power Strings (KMP求字符串循环节)
Description Problem D: Power Strings Given two strings a and b we define a*b to be their concatenati ...
随机推荐
- 某站出品2016织梦CMS进阶教程共12课(附文档+工具)
此为广告商内容使用最新版的dede cms建站 V5.7 sp1,经常注意后台的升级信息哦!一.安装DEDE的时候数据库的表前缀,最好改一下,不用dedecms默认的前缀dede_,随便一个名称即可. ...
- 后记:Cookie安全大辩论总结
前天,我发布在博客园上的某知名电商网站的Cookie漏洞引发园友们的热议,学到了很多知识,现在整理一下其中比较激烈的技术讨论.谁对谁错每个人自己心中都有一把称,很多时候都是我无法说服你,你也无法说服我 ...
- C#基础之IEnumerable
1.IEnumerable的作用 在使用Linq查询数据时经常以IEnumerable<T>来作为数据查询返回对象,在使用foreach进行遍历时需要该对象实现IEnumerable接口, ...
- 在nodeJs的Express框架下用TypeScript编写router路由出现import关键字错误的解决方案
问题出现场景 在项目中采用nodejs做中间层,做页面的首屏渲染,同时采用express作为主web框架,其中express的router页面路由我采用ts语言来编写.如下: //page.ts 文件 ...
- canvas 2d 贴图技术实践
最近在公司内部的技术协会论坛里闲逛的时候,无意中发现了一篇手淘前端大牛岑安两年前写的博文,讲述了canvas的2d贴图技术.看到后觉得相当神奇.于是就自己实现了一下.不过岑安前辈的那篇博文也只是大概讲 ...
- sql server存储过程编程
存储过程是一组完成特定功能的SQL 语句集合,经编译后存储在数据库中. 存储过程作为一个单元进行处理并以一个名称来标识.它能向用户返回数据.向数据库表中写入或修改数据等操作. 用户通过指定存储过程 ...
- crontab 定时任务
1 linux 系统需要安装crontab ;yum install vixie-cron crontabs 2 编写shell 脚本, save_dir=/var/local/mysqlbak/Ne ...
- 【Magenta 项目初探】手把手教你用Tensorflow神经网络创造音乐
原文链接:http://www.cnblogs.com/learn-to-rock/p/5677458.html 偶然在网上看到了一个让我很感兴趣的项目 Magenta,用Tensorflow让神经网 ...
- Graphql介绍(Introduction to GraphQL)
Introduction to GraphQL GraphQL介绍 Learn about GraphQL, how it works, and how to use it in this seri ...
- Linux14.04安装Mysql Linux公社
今天在Ubuntu 14.04下安装MySQL,本来是去官网下载安装包来安装的,可是安装之后却不能用,估计是要配置吧,在网上搜了很多的资料,结果还是失败.所以只好在软件源中安装,这样就省去很多不必要的 ...