2017ACM暑期多校联合训练 - Team 6 1001 HDU 6096 String (字符串处理 字典树)
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 (字符串处理 字典树)的更多相关文章
- 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 ...
- 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 ...
- 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 ...
- 2017ACM暑期多校联合训练 - Team 2 1003 HDU 6047 Maximum Sequence (线段树)
题目链接 Problem Description Steph is extremely obsessed with "sequence problems" that are usu ...
- 2017ACM暑期多校联合训练 - Team 1 1001 HDU 6033 Add More Zero (数学)
题目链接 Problem Description There is a youngster known for amateur propositions concerning several math ...
- 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 ...
- 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 ...
- 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 ...
- 2017ACM暑期多校联合训练 - Team 8 1002 HDU 6134 Battlestation Operational (数论 莫比乌斯反演)
题目链接 Problem Description The Death Star, known officially as the DS-1 Orbital Battle Station, also k ...
随机推荐
- 使用Dede破解Delphi软件实战
昨日练习了一把如何破解Delphi软件.下面和大家分享一下破解的过程,对初学者,希望有授之以渔的作用. 首先分析我们的目标软件,不要问我破解的是什么软件.保护知识产权,要从娃娃抓取. 目标软件是一个销 ...
- bzoj4754[JSOI2016]独特的树叶
这个题....别人写得怎么都....那么短啊? 我怎么....WA了好几次啊....怎么去loj扒了数据才调出来啊? 这个算法...怎么我还是不知道对不对啊 怎么回事啊怎么回事啊怎么回事啊? 请无视上 ...
- 程序猿必备技能:数据库管理——关于MySQL
一.初识MySQL 1.什么是数据库? 数据库(Database,DB)简而言之就是存放数据的仓库,是为了实现一定目的,按照某种规则组织起来的数据的集合. 2.使用数据库的必要性 (1)结构化存储大量 ...
- 【Java并发编程】之四:守护线程与线程阻塞的四种情况
守护线程 Java中有两类线程:User Thread(用户线程).Daemon Thread(守护线程) 用户线程即运行在前台的线程,而守护线程是运行在后台的线程. 守护线程作用是为其他前台线程 ...
- 【数据库_Mysql】<foreach>标签在Mysql中的使用
foreach属性 属性 描述 item 循环体中的具体对象.支持属性的点路径访问,如item.age,item.info.details.具体说明:在list和数组中是其中的对象,在map中是val ...
- 【Java】JAVA-加密-DES加密代码详解
package util; import java.security.SecureRandom; import javax.crypto.spec.DESKeySpec; import javax.c ...
- Sum of Consecutive Integers LightOJ - 1278(推公式 数学思维)
原文地址:https://blog.csdn.net/qq_37632935/article/details/79465213 给你一个数n(n<=10^14),然后问n能用几个连续的数表示; ...
- hive 排序和聚集
1.order by 是对数据进行全排序,属于标准排序语句 order by 会对输入做全局排序,因此只有一个reducer(多个reducer无法保证全局有序)只有一个reducer,会导致当输入规 ...
- 20135239 益西拉姆 linux内核分析 使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用
https://drive.wps.cn/preview#l/759e32d65654419cb765da932cdf5cdc 本次直接在wps上写的,因为不能连同图片一起粘贴过来,一个一个粘比较费时 ...
- 埃及分数&&The Rotation Game&&骑士精神——IDA*
IDA*:非常好用的搜索,可以解决很多深度浅,但是规模大的搜索问题. 估价函数设计思路:观察一步最多能向答案靠近多少. 埃及分数 题目大意: 给出一个分数,由分子a 和分母b 构成,现在要你分解成一系 ...