题目链接

Problem Description
Bob has a dictionary with N words in it.
Now there is a list of words in which the middle part of the word has continuous letters disappeared. The middle part does not include the first and last character.
We only know the prefix and suffix of each word, and the number of characters missing is uncertain, it could be 0. But the prefix and suffix of each word can not overlap.
For each word in the list, Bob wants to determine which word is in the dictionary by prefix and suffix.
There are probably many answers. You just have to figure out how many words may be the answer.
 
Input
The first line of the input gives the number of test cases T; T test cases follow.
Each test case contains two integer N and Q, The number of words in the dictionary, and the number of words in the list.
Next N line, each line has a string Wi, represents the ith word in the dictionary (0<|Wi|≤100000)
Next Q line, each line has two string Pi , Si, represents the prefix and suffix of the ith word in the list (0<|Pi|,|Si|≤100000,0<|Pi|+|Si|≤100000)
All of the above characters are lowercase letters.
The dictionary does not contain the same words.

Limits
T≤5
0<N,Q≤100000
∑Si+Pi≤500000
∑Wi≤500000

 
Output
For each test case, output Q lines, an integer per line, represents the answer to each word in the list.
 
Sample Input
1
4 4
aba
cde
acdefa
cdef
a a
cd ef
ac a
ce f
 
Sample Output
2
1
1
0
 
 
题意:有 n 个由小写字母构成的串,现在有q次询问,每次给一个前缀和后缀,求这n个串中有多少个串满足给的前缀和后缀,前缀和后缀不能在这个字符串中重叠?
 
思路:对于给的n个串s[i],修改为 s[i] = s[i] + "_" + s[i] ,对于每次询问输入的前缀pre和后缀suf,修改为str=suf+"_"+pre,对这q次询问的前缀后缀构成的串 构建tire树,然后用AC自动机匹配跑一下即可。但是这样会存在冗余,例如:aaa,前缀aa 后缀aa,那么也会匹配上,所以比较时还得判断一下长度。
 
代码如下:
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <string>
#include <queue>
#include <vector>
using namespace std;
const int N=1e5+;
string s[N];
struct Node{
Node *son[];
Node *fail;
int flag;
int len;
}tr[*N];
Node *root;
queue<Node*>Q;
int ans[N];
vector<int>v[N];
int tot; void init()
{
tot=;
memset(ans,,sizeof(ans));
root=&tr[];
while(!Q.empty()) Q.pop();
for(int i=;i<N;i++) v[i].clear();
for(int i=;i<*N;i++)
{
tr[i].flag=;
tr[i].fail=NULL;
for(int j=;j<;j++) tr[i].son[j]=NULL;
}
}
void build(string s,int id)
{
Node *now=root;
for(int i=;i<s.length();i++)
{
int x=s[i]-'_';
if(!now->son[x]) now->son[x]=&tr[++tot];
now=now->son[x];
}
if(now->flag) {
v[now->flag].push_back(id);
return ;
}
now->flag=id;
now->len=s.length();
}
void setFail()
{
Q.push(root);
while(!Q.empty())
{
Node *now=Q.front(); Q.pop();
for(int i=;i<;i++)
{
if(now->son[i])
{
Node *p=now->fail;
while(p && (!(p->son[i]))) p=p->fail;
now->son[i]->fail=(p)?p->son[i]:root;
Q.push(now->son[i]);
}
else now->son[i]=(now!=root)?now->fail->son[i]:root;
}
}
}
void query(string s)
{
Node *now=root;
int len=s.length();
for(int i=;i<len;i++)
{
int x=s[i]-'_';
now=now->son[x];
Node *p=now;
while(p!=root)
{
if(p->flag && p->len<=len/+) ans[p->flag]++;
p=p->fail;
}
}
}
int main()
{
int T; cin>>T;
while(T--)
{
init();
int n,q; scanf("%d%d",&n,&q);
for(int i=;i<=n;i++)
{
cin>>s[i];
s[i]=s[i]+"_"+s[i];
}
for(int i=;i<=q;i++)
{
string s1,s2; cin>>s1>>s2;
string ss=s2+"_"+s1;
build(ss,i);
}
setFail();
for(int i=;i<=n;i++)
{
query(s[i]);
}
for(int i=;i<=q;i++) ///处理相同的前后缀;
{
for(int j=;j<v[i].size();j++)
ans[v[i][j]]=ans[i];
}
for(int i=;i<=q;i++) printf("%d\n",ans[i]);
}
return ;
}

hdu 6096---String(AC自动机)的更多相关文章

  1. 2017多校第6场 HDU 6096 String AC自动机

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6096 题意:给了一些模式串,然后再给出一些文本串的不想交的前后缀,问文本串在模式串的出现次数. 解法: ...

  2. HDU 6096 String (AC自动机)

    题意:给出n个字符串和q个询问,每次询问给出两个串 p 和 s .要求统计所有字符串中前缀为 p 且后缀为 s (不可重叠)的字符串的数量. 析:真是觉得没有思路啊,看了官方题解,真是好复杂. 假设原 ...

  3. ZOJ 3228 Searching the String(AC自动机)

    Searching the String Time Limit: 7 Seconds      Memory Limit: 129872 KB Little jay really hates to d ...

  4. HDU 6096 String(AC自动机+树状数组)

    题意 给定 \(n\) 个单词,\(q\) 个询问,每个询问包含两个串 \(s_1,s_2\),询问有多少个单词以 \(s_1\) 为前缀, \(s_2\) 为后缀,前后缀不能重叠. \(1 \leq ...

  5. hdu 6086 -- Rikka with String(AC自动机 + 状压DP)

    题目链接 Problem Description As we know, Rikka is poor at math. Yuta is worrying about this situation, s ...

  6. HDU 2222(AC自动机模板题)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2222 题目大意:多个模式串.问匹配串中含有多少个模式串.注意模式串有重复,所以要累计重复结果. 解题 ...

  7. HDU 2222 (AC自动机模板题)

    题意: 给一个文本串和多个模式串,求文本串中一共出现多少次模式串 分析: ac自动机模板,关键是失配函数 #include <map> #include <set> #incl ...

  8. Keywords Search - HDU 2222(AC自动机模板)

    题目大意:输入几个子串,然后输入一个母串,问在母串里面包含几个子串.   分析:刚学习的AC自动机,据说这是个最基础的模板题,所以也是用了最基本的写法来完成的,当然也借鉴了别人的代码思想,确实是个很神 ...

  9. HDU 2296 Ring [AC自动机 DP 打印方案]

    Ring Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submissio ...

随机推荐

  1. phpstudy:80端口被占用解决方案总结

    一开始因为要安装新的软件,同时也由于一直电脑很卡,所以直接重装系统,从WIN8变成WIN10,然后不知道为什么,phpstudy里面80端口被占用了!被占用了!现在找到了两种方法解决! 第一种 该端口 ...

  2. java泛型(整理)

    1 泛型基础知识 泛型需要理解两个关键点:1)类型擦除 2)类型转换 1)类型擦除 泛型有个很重要的概念,是类型擦除.正确理解泛型概念的首要前提是理解类型擦除(type erasure). Java中 ...

  3. zabbix 配置发送邮件报警

    标签:监控/SQLServer/Windows 概述 本篇文章主要介绍如何配置zabbix借助外部邮件进行发送邮件报警,zabbix通过配置文件调用mailx来进行邮件的发送.在Centos6以上的版 ...

  4. 如何重置密码 oracle sys和system

    有时候我们会忘记oracle sys和system的密码,不用担心,通过sqlplus即可修改密码.只能修改,不能找回. 方法如下: 1.打开 cmd界面,输入sqlplus /nolog 显示结果如 ...

  5. 关于Oracle连接超时的问题

    测试环境ORACLE 11.2.0. 如果连接池设置单个连接闲置时间大于数据库连接超时时间,则连接池中的连接发出数据请求时会出现Connect timeout occurred错误, 这是由于连接超时 ...

  6. 2016 "Bird Cup" ICPC7th@ahstu--“波导杯”安徽科技学院第七届程序设计大赛

    "波导杯"安徽科技学院第七届程序设计大赛 Contest - 2016 "Bird Cup" ICPC7th@ahstu Start time:  2016-0 ...

  7. C语言程序设计进阶 翁恺 第4周编程练习

    第4周编程练习 查看帮助 返回 第4周编程练习 依照学术诚信条款,我保证此作业是本人独立完成的. 温馨提示: 1.本次作业属于Online Judge题目,提交后由系统即时判分. 2.学生可以在作业 ...

  8. String对象常用的一些方法

    anchor() 创建 HTML 锚. big() 用大号字体显示字符串. blink() 显示闪动字符串. bold() 使用粗体显示字符串. charAt() 返回在指定位置的字符. charCo ...

  9. python学习===从一个数中分解出每个数字

    题目:打印出所有的"水仙花数",所谓"水仙花数"是指一个三位数,其各位数字立方和等于该数本身.例如:153是一个"水仙花数",因为153=1 ...

  10. windows 快捷方式(.lnk)代码执行漏洞(CVE-2017-8464 )[附EXP生成工具]

    最近看到网上曝光了一个windows远程代码执行的漏洞,黑客可以通过一个快捷方式在用户电脑上执行任意指令,于是便对该漏洞进行了部分分析. 1. 漏洞描述: MicrosoftWindows .LNK  ...