题目链接

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个查询,每个查询包含A、B两个字符串,问在给定的n个字符串中,有多少个字符串满足前缀是A,后缀是B且前缀后缀没有重叠部分

分析:

对查询离线处理,给定的字符串保存下来,而对查询的前缀后缀建立字典树,建树过程如下,假设有ac ef这种查询情况:

先将ef翻转过来使得查询变为ac fe, 之后再加一个特殊字符将前缀于后缀连接起来变为ac#fe,对ac#fe建立字典树,并在这个字符串的结尾处设置一个值,这个值为当前查询前后缀的下标k(即第几个查询),如果查询的前缀后缀都相同的,取第一个出现的就好了。

然后是对给定的字符串查询,就是查询每个字符串对查询的贡献,假设有ac ef的查询,有给定的字符串acdef,在字典树上匹配的时候有先有0->a,发现没有a#,继续,然后0->a->c发现ac#有,那么就开始将acdef的字符串反过来匹配了,变成0->a->c->#->f->e 因为f没有值,到达e的时候发现e这处节点有值k,那么就是ans[k]++。

代码:

#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
typedef long long ll;
const int maxn = 6e5 + 10;
const int INF = 1e9 + 10;
const int mod = 1e9 + 7;
using namespace std; int val[maxn], sz;
int ch[maxn][27];
char str[maxn];
char s[maxn];
int n,T,q;
int len[maxn], ans[maxn];
int nxt[maxn]; int __insert(int st, int l, int r, int v, int flag)///根节点,左右区间,表示前后缀而且只需要在后缀记录数目,正逆序标记
{
int u = st, t = abs(r - l) + 1;
for(int i = l; t--; i += flag)///循环遍历整个前缀或者后缀
{
int c = s[i] - 'a';
if(!ch[u][c])
{
memset(ch[sz], 0, sizeof ch[sz]);
val[sz] = 0;
ch[u][c] = sz++;
}
u = ch[u][c];
}
if(v)///表示当前插入的这个是后缀的情况
{
if(val[u] == 0) val[u] = v;
else nxt[v] = val[u];///如果有多个的后缀是以同一个字母结尾的,都取同一个就好了
}
return u;
} void query(int L, int R)///查询一个单词
{
int u = 0;
for(int i = L; i <= R; i++)
{
int c = str[i] - 'a';
if(!ch[u][c]) return ;///压根就没有这个前缀的单词
u = ch[u][c];
if(!ch[u][26]) continue;///找到这个前缀了
int st = ch[u][26];
for(int j = R; j > i; j--)////反过来找后缀
{
int k = str[j] - 'a';
st = ch[st][k];
if(!st) break;
if(val[st]) ans[val[st]]++;
}
}
} int main()
{
scanf("%d", &T);
while(T--)
{
sz = 1;
memset(ch[0], 0, sizeof ch[0]);
val[0] = 0;
scanf("%d %d", &n, &q);
for(int i = 1; i <= q; i++) nxt[i] = i;
int num = 0;
for(int i = 0; i < n; i++)
{
scanf("%s", str + num);
len[i] = strlen(str + num);
num += len[i];
}
for(int i = 1; i <= q; i++)
{
ans[i] = 0;
scanf("%s", s);
int l1 = strlen(s);
s[l1++] = 'a' + 26;
scanf("%s", s + l1);
int l2 = strlen(s + l1);
int node = __insert(0, 0, l1 - 1, 0, 1);
__insert(node, l2 + l1 - 1, l1, i, -1);
}
num = 0;
for(int i = 0; i < n; i++)
{
query(num, num + len[i] - 1);
num += len[i];
}
for(int i = 1; i <= q; i++)
{
printf("%d\n", ans[nxt[i]]);
}
}
return 0;
}

2017ACM暑期多校联合训练 - Team 6 1001 HDU 6096 String (字符串处理 字典树)的更多相关文章

  1. 2017ACM暑期多校联合训练 - Team 4 1004 HDU 6070 Dirt Ratio (线段树)

    题目链接 Problem Description In ACM/ICPC contest, the ''Dirt Ratio'' of a team is calculated in the foll ...

  2. 2017ACM暑期多校联合训练 - Team 5 1001 HDU 6085 Rikka with Candies (模拟)

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

  3. 2017ACM暑期多校联合训练 - Team 2 1001 HDU 6045 Is Derek lying? (模拟)

    题目链接 Problem Description Derek and Alfia are good friends.Derek is Chinese,and Alfia is Austrian.Thi ...

  4. 2017ACM暑期多校联合训练 - Team 2 1003 HDU 6047 Maximum Sequence (线段树)

    题目链接 Problem Description Steph is extremely obsessed with "sequence problems" that are usu ...

  5. 2017ACM暑期多校联合训练 - Team 1 1001 HDU 6033 Add More Zero (数学)

    题目链接 Problem Description There is a youngster known for amateur propositions concerning several math ...

  6. 2017ACM暑期多校联合训练 - Team 9 1005 HDU 6165 FFF at Valentine (dfs)

    题目链接 Problem Description At Valentine's eve, Shylock and Lucar were enjoying their time as any other ...

  7. 2017ACM暑期多校联合训练 - Team 9 1010 HDU 6170 Two strings (dp)

    题目链接 Problem Description Giving two strings and you should judge if they are matched. The first stri ...

  8. 2017ACM暑期多校联合训练 - Team 8 1006 HDU 6138 Fleet of the Eternal Throne (字符串处理 AC自动机)

    题目链接 Problem Description The Eternal Fleet was built many centuries ago before the time of Valkorion ...

  9. 2017ACM暑期多校联合训练 - Team 8 1002 HDU 6134 Battlestation Operational (数论 莫比乌斯反演)

    题目链接 Problem Description The Death Star, known officially as the DS-1 Orbital Battle Station, also k ...

随机推荐

  1. 树莓派无显示器、无网线,优盘(U盘)启动,远程桌面

    版权声明:若无来源注明,Techie亮博客文章均为原创. 转载请以链接形式标明本文标题和地址: 本文标题:树莓派无显示器.无网线,优盘(U盘)启动,远程桌面     本文地址:http://techi ...

  2. JDK1.8 之Lambda

    Lambda 理解的了很久才有一点小感觉. 语法 lambda表达式的特点,它的语法如下面. parameter -> expression body 下面是一个lambda表达式的重要特征. ...

  3. 第112天:javascript中函数预解析和执行阶段

    关于javascript中的函数:  1.预解析:把所有的函数定义提前,所有的变量声明提前,变量的赋值不提前  2.执行 :从上到下执行,但有例外(setTimeout,setInterval,aja ...

  4. [BZOJ3172]单词

    3172: [Tjoi2013]单词 Time Limit: 10 Sec  Memory Limit: 512 MB Description 某人读论文,一篇论文是由许多单词组成.但他发现一个单词会 ...

  5. TCP的拥塞控制 (一)

    拥塞控制不同于流量控制,拥塞控制是在拥塞发生时,发送方根据一定的反馈,主动调节自己的发送速率,以防止拥塞恶化的行为. 1.   网络拥塞 路由器是网络中的关键组件,其内部有一定量的缓冲区,用于缓存来不 ...

  6. 跟我学Spring Cloud(Finchley版)-17-Zuul路由配置详解

    但在实际项目中,往往需要自己定义路由规则,Zuul的路由配置非常灵活.简单,本节详细讲解Zuul的路由配置. 一.自定义指定微服务的访问路径 配置zuul.routes.指定微服务的serviceId ...

  7. Redis的List链表类型命令

    List是一个链表结构,主要功能是push.pop.获取一个范围的所有值等等,操作中key理解为链表的名字.list类型其实就是一个每个子元素都是string类型的双向链表.我们可以通过push.po ...

  8. 深入详解windows安全认证机制ntlm&Kerberos

    0x01 为什么要理解windows 安全认证机制: 加深对后续各种漏洞利用的理解深度,还是那句话,要知其然,更要知其所以然,不废话,咱们直接开始 0x02 windows认证协议主要有以下两种: 基 ...

  9. powershell网络钓鱼获取用户密码

    1.powershell网络钓鱼脚本: https://raw.githubusercontent.com/enigma0x3/Invoke-LoginPrompt/master/Invoke-Log ...

  10. 埃及分数&&The Rotation Game&&骑士精神——IDA*

    IDA*:非常好用的搜索,可以解决很多深度浅,但是规模大的搜索问题. 估价函数设计思路:观察一步最多能向答案靠近多少. 埃及分数 题目大意: 给出一个分数,由分子a 和分母b 构成,现在要你分解成一系 ...