HDU 2846:Repository(Trie)

http://acm.hdu.edu.cn/showproblem.php?pid=2846

题意:给出N个模式串,再给出M个文本串,问每一个文本串在多少个模式串中出现。

思路:平时都是找前缀的,这里将模式串s[1……len]的每一个[i,len]的子串都插入,这样就可以满足条件。还要注意如果两个子串都为同一个模式串的子串,不能重复计数。可以用一个id数组装上一次是哪个串的id,如果id相同就不要重复计数了。

 1 #include <cstdio>
 2 #include <algorithm>
 3 #include <iostream>
 4 #include <cstring>
 5 #include <string>
 6 #include <cmath>
 7 #include <queue>
 8 #include <vector>
 9 using namespace std;
10 #define N 2000010
11 char s[25];
12 struct Trie
13 {
14     int ch[N][26], num, cnt[N], id[N]; //空间尽量开大点
15
16     void init()
17     {
18         memset(ch[0], 0, sizeof(ch[0]));
19         num = 1;
20     }
21
22     void update(char *s, int index)
23     {
24         int u = 0;
25         int len = strlen(s);
26         for(int i = 0; i < len; i++) {
27             int tmp = s[i] - ‘a‘;
28             if(!ch[u][tmp]) {
29                 memset(ch[num], 0, sizeof(ch[num]));
30                 cnt[num] = 0;
31                 id[num] = 0;
32                 ch[u][tmp] = num++;
33             }
34             u = ch[u][tmp];
35             if(id[u] != index) cnt[u]++;
36             id[u] = index; //标记上一个是否是相同的串,如果相同不能重复计数
37         }
38     }
39
40     int query(char *s)
41     {
42         int u = 0;
43         int len = strlen(s);
44         for(int i = 0; i < len; i++) {
45             int tmp = s[i] - ‘a‘;
46             if(!ch[u][tmp]) return 0;
47             u = ch[u][tmp];
48         }
49         return cnt[u];
50     }
51 }trie;
52
53 int main()
54 {
55     int n;
56     scanf("%d", &n);
57     trie.init();
58     for(int i = 1; i <= n; i++) {
59         scanf("%*c%s", s);
60         int len = strlen(s);
61         for(int j = 0; j < len; j++) {
62             trie.update(s + j, i); //每一个串的以s[j]开头的子串都要插入
63         }
64     }
65     scanf("%d", &n);
66     for(int i = 0; i < n; i++) {
67         scanf("%*c%s", s);
68         printf("%d\n", trie.query(s));
69     }
70     return 0;
71 }
时间: 2024-10-09 07:33:48

HDU 2846:Repository(Trie)的相关文章

HDU 1260:Tickets(DP)

Tickets Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 923    Accepted Submission(s): 467 Problem Description Jesus, what a great movie! Thousands of people are rushing to the cinema. However,

HDU 1671 Phone List (Trie)

Phone List Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 12879    Accepted Submission(s): 4391 Problem Description Given a list of phone numbers, determine if it is consistent in the sense th

机房测试:race(trie)

题目: 分析: 先不考虑天数的限制,直接对每一个人建一颗trie. 对于每一个人来说,他的x的贡献来源于trie树上所有在他右边的点(都比他大). 将每一个子树所有的叶子结点记为f,x^2=(f1+f2+……fx)^2 将右式拆开看:f i *f i + f i * f j *2(枚举i,j统计贡献,*2是因为 i 和 j 可以交换) 再加上天数的限制:每一个人的A[i]异或上天数 j,相当于trie树的形态发生改变了(01边交换) 对于1来说,又多了一部分贡献,也就是说,对于右子树来说,当且仅

HDU 5791:Two(DP)

http://acm.hdu.edu.cn/showproblem.php?pid=5791 Two Problem Description Alice gets two sequences A and B. A easy problem comes. How many pair of sequence A' and sequence B' are same. For example, {1,2} and {1,2} are same. {1,2,4} and {1,4,2} are not s

HDU 1251 统计难题 (Trie)

统计难题 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131070/65535 K (Java/Others) Total Submission(s): 22182    Accepted Submission(s): 9391 Problem Description Ignatius近期遇到一个难题,老师交给他非常多单词(仅仅有小写字母组成,不会有反复的单词出现),如今老师要他统计出以某个字符串为前缀的单词数量(单词本身也是自

HDU 1251-统计难题(Trie)

题意: 给一组单词 开始提问每次给一个串求该串是上面几个单词的前缀 分析: 没给数据规模,但用链表写ME好几次,又用数组写开小RE了,试了几次才过了,真是醉了... #include <map> #include <set> #include <list> #include <cmath> #include <queue> #include <stack> #include <cstdio> #include <ve

HDU 1247 Hat&#39;s words(Trie)

HDU 1247 Hat's words(Trie) ACM 题目地址: HDU 1247 Hat's words 题意: 给些单词,问每个单词是否能用另外两个单词拼出. 分析: 直接保存到trie里面,然后暴力切割查询即可. 代码: /* * Author: illuz <iilluzen[at]gmail.com> * File: 1247.cpp * Create Date: 2014-09-24 11:04:11 * Descripton: */ #include <cstdio

HDU 1045 - Fire Net (最大独立集)

题意:给你一个正方形棋盘.每个棋子可以直线攻击,除非隔着石头.现在要求所有棋子都不互相攻击,问最多可以放多少个棋子. 这个题可以用搜索来做.每个棋子考虑放与不放两种情况,然后再判断是否能互相攻击来剪枝.最后取可以放置的最大值. 这里我转化成求最大独立集来做. 首先将每个空地编号,对于每个空地,与该位置可以攻击到的空地连边.找最多的空地使得不互相攻击,即求该图的最大独立集.与搜索做法基本一致,但是说法略有不同. 1 #include<iostream> 2 #include<cstring

hdu oj1102 Constructing Roads(最小生成树)

Constructing Roads Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 13995    Accepted Submission(s): 5324 Problem Description There are N villages, which are numbered from 1 to N, and you should