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 ...
随机推荐
- 手把手教你使用markdown
这是 [认真学编程] 系列的 第3篇 文章,欢迎点赞分享.写留言,这些都是对我最好的支持. 全文2300字,阅读预计5分钟] 在前面几篇文章中,多次提到装X神器markdown,本人也是markdow ...
- 分析cocos2d-x中的CrystalCraze示例游戏
cocos2d-x自带了不少示例,以及几个比较简单的游戏,不过这些游戏都是用javascript binding(SpiderMonkey)做的,所以我猜测javascript binding可能是c ...
- 准备.Net转前端开发-WPF界面框架那些事,UI快速实现法
题外话 打开博客园,查看首页左栏的”推荐博客”,排名前五的博客分别是(此处非广告):Artech.小坦克.圣殿骑士.腾飞(Jesse).数据之巅.再看看它们博客的最新更新时间:Artech(2014- ...
- Validform表单验证总结
近期项目里用到了表单的验证,选择了Validform_v5.3.2. 先来了解一下一些基本的参数: 通用表单验证方法:Demo: $(".demoform").Validform( ...
- 用nhibernate的几点小经验
最近几个月都在用nhibernate做项目.写几点经验. 1. 解决Transient object exception 原项目是用Entity Framework做的.现在是用nhibernate代 ...
- CSS与JQuery的相关问题
文字隐藏:p div里面的文字过长时隐藏文字: overflow:hidden; text-overflow:ellipsis; white-space:nowrap; --------------- ...
- js表单提交,面向对象
一.js表单验证之后再提交 1.普通按钮onclick函数调用表单的submit()函数 <input type=button name="submit1" value=&q ...
- jquery插件之jquery-validation
equalTo方法: equalTo: function( value, element, param ) { // Bind to the blur event of the target in o ...
- android 随记 ContentValues
ContentValues 和HashTable类似都是一种存储的机制 但是两者最大的区别就在于,contenvalues只能存储基本类型的数据,像string,int之类的,不能存储对象这种东西,而 ...
- Hibernate用注解实现实体类和表的映射
数据库mysql: 1.一对一 person50表password50表是一对一的关系: password50表中有外键 person_id person实体类: package com.c50.en ...