[HDOJ2846]Repository(字典树)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2846

题意:求一堆串中有多少个以0开始的子串包含目标串。

可以把所有的串符合要求的子串放入字典树统计。这时候会有一个问题,那就是adddd这样的单词:样例中已经说明了,这样的单词明显是只算一次的。所以可以在字典树中打标记,每一个节点最后更新的时候的字符串是哪个。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3
 4 typedef struct Node {
 5     Node* next[26];
 6     int cnt, id;
 7 }Node;
 8 int n, q, ncnt;
 9 char tmp[22];
10 Node memory[350000];
11 Node* rt;
12
13 void insert(Node* rt, char* s, int id) {
14     Node* p = rt;
15     for(int i = 0; s[i]; i++) {
16         int x = s[i] - ‘a‘;
17         if(p->next[x] == NULL) {
18             p->next[x] = &memory[ncnt++];
19             p->next[x]->id = -1;
20         }
21         p = p->next[x];
22         if(id != p->id) {
23             p->cnt++;
24             p->id = id;
25         }
26     }
27 }
28
29 int query(Node* rt, char* s) {
30     Node* p = rt;
31     for(int i = 0; s[i]; i++) {
32         int x = s[i] - ‘a‘;
33         if(p->next[x] == NULL) return 0;
34         p = p->next[x];
35     }
36     return p->cnt;
37 }
38
39 int main() {
40     // freopen("in", "r", stdin);
41     while(~scanf("%d", &n)) {
42         ncnt = 0;
43         memset(memory, 0, sizeof(memory));
44         rt = &memory[ncnt++];
45         memset(rt->next, 0, sizeof(rt->next));
46         for(int i = 0; i < n; i++) {
47             scanf("%s", tmp);
48             for(int j = 0; tmp[j]; j++) {
49                 insert(rt, tmp+j, i);
50             }
51         }
52         scanf("%d", &q);
53         while(q--) {
54             scanf("%s", tmp);
55             printf("%d\n", query(rt, tmp));
56         }
57     }
58     return 0;
59 }
时间: 2024-10-28 18:49:45

[HDOJ2846]Repository(字典树)的相关文章

hdu 2846 Repository 字典树

// hdu 2846 Repository 字典树 // // 题目大意: // // 有n个字符串,m个待询问的字符串,问这些字符串里面以该询问的 // 字符串为子串的字符串有多少个 // // 解题思路: // // 字典树,将字符串的所有子串插入到字典树中,并设立一个No.标识 // 以免重计数.最后查询就好了 // // 感悟: // // 这题的数据量有点大,虽然p是10000,但是长度是20,单个字符串的 // 最大子串数粗略的估计是 20 * 20 ,所以开的空间也要比较大.开始

HDU 2846 Repository(字典树,标记)

题目 字典树,注意初始化的位置~!!位置放错,永远也到不了终点了org.... 我是用数组模拟的字典树,这就要注意内存开多少了,,要开的不大不小刚刚好真的不容易啊.... 我用了val来标记是否是同一个串分解而来的,保存的是串的编号 num记录数目. //string &replace(iterator first0, iterator last0,const_iterator first, const_iterator last); //把[first0,last0)之间的部分替换成[firs

HDU 2846 Repository (字典树 后缀建树)

Repository Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 2932    Accepted Submission(s): 1116 Problem Description When you go shopping, you can search in repository for avalible merchandises

hdu 2846 Repository 字典树的一种变形

Repository Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 2633    Accepted Submission(s): 1028 Problem Description When you go shopping, you can search in repository for avalible merchandises

HDU2846 Repository(字典树)

Repository Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 5761    Accepted Submission(s): 1911 Problem Description When you go shopping, you can search in repository for avalible merchandises b

HDU 2846 Repository(字典树)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2846 题目:输入个n个词典串,然后输入q个串,对这q个串分别输出每个串都是几个词典串的子串. 思路:因为要包含子串,比如abd,将串abd,bd,d都插入字典树,然后每个节点下统计子树个数,直接查找前缀就可以了.但需要注意dcda这种的,需要插入dcda,cda,da,a,这个时候d下面的子树应该是一个而不是2个,因为dcda和da属于同一个词典串.所以在插入的时候进行处理即可. 代码 #inclu

Repository HDU - 2846 字典树

题意:给出很多很多很多很多个 单词 类似搜索引擎一下 输入一个单词 判断有一个字符串包含这个单词 思路:字典树变体,把每个单词的后缀都扔字典树里面,这里要注意dd是一个单词 但是把d 和dd都放字典树 拿d匹配这一个单词会匹配两次 所以要开个数组记录一下上一个使该位置数量加一的字符串 如果该字符串不是同一个 那就可以加加了 TLE:还是数组大小的问题 字典树有毒!因为一个字符串可以拆成很多个后缀所以必须开大,开大了就过了... 1 #include<bits/stdc++.h> 2 using

hdu 1251 统计难题(字典树)

Problem Description Ignatius最近遇到一个难题,老师交给他很多单词(只有小写字母组成,不会有重复的单词出现),现在老师要他统计出以某个字符串为前缀的单词数量(单词本身也是自己的前缀). Input 输入数据的第一部分是一张单词表,每行一个单词,单词的长度不超过10,它们代表的是老师交给Ignatius统计的单词,一个空行代表单词表的结束.第二部分是一连串的提问,每行一个提问,每个提问都是一个字符串. 注意:本题只有一组测试数据,处理到文件结束. Output 对于每个提

51nod round3# 序列分解(折半枚举+字典树)

小刀和大刀是双胞胎兄弟.今天他们玩一个有意思的游戏. 大刀给小刀准备了一个长度为n的整数序列.小刀试着把这个序列分解成两个长度为n/2的子序列. 这两个子序列必须满足以下两个条件: 1.他们不能相互重叠. 2.他们要完全一样. 如果小刀可以分解成功,大刀会给小刀一些糖果. 然而这个问题对于小刀来说太难了.他想请你来帮忙. Input 第一行给出一个T,表示T组数据.(1<=T<=5) 接下来每一组数据,输入共2行. 第一行包含一个整数n (2<=n<=40且为偶数). 第二行给出n