[字典树,trie树] 树之呼吸-肆之型-前缀统计
| D.树之呼吸-肆之型-前缀统计 | |||||
|
|||||
| Description | |||||
|
给定 n 个字符串 S1,S2,...,Sn。 接下来进行 m 次询问,每次询问给定一个字符串 T, 求 S1 ~ Sn 中有多少个字符串是 T 的前缀。 |
|||||
| Input | |||||
|
输入第一行为一个正整数 case,表示测试数据组数; 对于每组测试数据,输入第一行为一个正整数 n,表示给定的字符串数; 接下来 n 行,给出 n 个字符串 S1 ~ Sn; 接下来一行一个正整数 m,表示询问数; 接下来 m 行,给出 m 个询问串 T1 ~ Tm; 保证: case <= 50; 给定串和询问串均只由大小写字母组成; 给定串和询问串的总长均不超过 2e5。 |
|||||
| Output | |||||
| 对于每组测试数据,输出 m 行,每行一个整数,表示有多少个给定串是 T1 ~ Tm 的前缀。 | |||||
| Sample Input | |||||
|
2 3 aab aa a 3 aa aab aabc 3 ABA ABA AAB 3 AB ABAab AAB |
|||||
| Sample Output | |||||
|
2 3 3 0 2 1 |
|||||
| Author | |||||
| 陈鑫 |
题意: 给定 n 个字符串 S1,S2,...,Sn.
接下来进行 m 次询问,每次询问给定一个字符串 T,
求 S1 ~ Sn 中有多少个字符串是 T 的前缀.
思路:给n个单词建一个字典树,在枚举Ti的前缀,看字典树中是否存在这个前缀,如果存在则答案加上这个单词出现的次数
注意:
这里正常来说按题意数组长度应该开2e5,但用memset会超时,正确做法是用fill并且去掉第一次初始化(把初始化放结尾),这里开1e5能过是因为数据水了,
注意字母有大小写A在a的前面,所以s[i]-'A',来得到字母的编号
ed[rt]标记不仅可以表示是否存在,也可以用来统计出现的次数
注意如果用了freopen则不能关闭流同步,也就是ios::sync_with_stdio(0),否则可以关闭流同步
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int amn=1e5+; ///这里正常来说应该开2e5,但用memset会超时,正确做法是用fill并且去掉第一次初始化(把初始化放结尾),这里开1e5能过是因为数据水了,
int tr[amn][],ed[amn],tot,x,ans,len,rt;
void init(){
memset(tr,,sizeof tr); ///在2e5的情况下的正确做法是用fill,不然用memset会超时
memset(ed,,sizeof ed);
tot=;
}
char s[amn];
void add(){
len=strlen(s),rt=;
for(int i=;i<len;i++){
x=s[i]-'A'; ///注意字母有大小写A在a的前面,所以s[i]-'A',来得到字母的编号
if(!tr[rt][x])tr[rt][x]=++tot;
rt=tr[rt][x];
}
ed[rt]++; ///这里由ed[rt]=1,变为了ed[rt]++,可以统计相同的单词出现了几次
}
void sol(){
len=strlen(s),rt=,ans=;
for(int i=;i<len;i++){
x=s[i]-'A';
if(!tr[rt][x])return; ///如果下面没结点就不用匹配了
rt=tr[rt][x];
if(ed[rt])ans+=ed[rt]; ///如果出现了一个单词,则答案加上单词出现的次数
}
}
int main(){
// freopen("in.txt","r",stdin);
// cin.sync_with_stdio(0);
///注意如果用了freopen则不能关闭流同步,也就是ios::sync_with_stdio(0),否则可以关闭流同步
int T,n,m;scanf("%d",&T);
while(T--){
scanf("%d",&n);
init();
while(n--){
cin>>s;
add();
}
scanf("%d",&m);
while(m--){
cin>>s;
sol();
printf("%d\n",ans);
}
}
}
/**
题意: 给定 n 个字符串 S1,S2,...,Sn.
接下来进行 m 次询问,每次询问给定一个字符串 T,
求 S1 ~ Sn 中有多少个字符串是 T 的前缀.
思路:给n个单词建一个字典树,在枚举Ti的前缀,看字典树中是否存在这个前缀,如果存在则答案加上这个单词出现的次数
注意:
这里正常来说按题意数组长度应该开2e5,但用memset会超时,正确做法是用fill并且去掉第一次初始化(把初始化放结尾),这里开1e5能过是因为数据水了,
注意字母有大小写A在a的前面,所以s[i]-'A',来得到字母的编号
ed[rt]标记不仅可以表示是否存在,也可以用来统计出现的次数
注意如果用了freopen则不能关闭流同步,也就是ios::sync_with_stdio(0),否则可以关闭流同步
**/
[字典树,trie树] 树之呼吸-肆之型-前缀统计的更多相关文章
- 数据结构图解(递归,二分,AVL,红黑树,伸展树,哈希表,字典树,B树,B+树)
递归反转 二分查找 AVL树 AVL简单的理解,如图所示,底部节点为1,不断往上到根节点,数字不断累加. 观察每个节点数字,随意选个节点A,会发现A节点的左子树节点或右子树节点末尾,数到A节点距离之差 ...
- 字典树(Trie树)的实现及应用
>>字典树的概念 Trie树,又称字典树,单词查找树或者前缀树,是一种用于快速检索的多叉树结构,如英文字母的字典树是一个26叉树,数字的字典树是一个10叉树.与二叉查找树不同,Trie树的 ...
- [转载]字典树(trie树)、后缀树
(1)字典树(Trie树) Trie是个简单但实用的数据结构,通常用于实现字典查询.我们做即时响应用户输入的AJAX搜索框时,就是Trie开始.本质上,Trie是一颗存储多个字符串的树.相邻节点间的边 ...
- [POJ] #1002# 487-3279 : 桶排序/字典树(Trie树)/快速排序
一. 题目 487-3279 Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 274040 Accepted: 48891 ...
- 『字典树 trie』
字典树 (trie) 字典树,又名\(trie\)树,是一种用于实现字符串快速检索的树形数据结构.核心思想为利用若干字符串的公共前缀来节约储存空间以及实现快速检索. \(trie\)树可以在\(O(( ...
- 字典树trie学习
字典树trie的思想就是利用节点来记录单词,这样重复的单词可以很快速统计,单词也可以快速的索引.缺点是内存消耗大 http://blog.csdn.net/chenleixing/article/de ...
- 【转】B树、B-树、B+树、B*树、红黑树、 二叉排序树、trie树Double Array 字典查找树简介
B 树 即二叉搜索树: 1.所有非叶子结点至多拥有两个儿子(Left和Right): 2.所有结点存储一个关键字: 3.非叶子结点的左指针指向小于其关键字的子树,右指针指向大于其关键字的子树: 如: ...
- 字典树 trie树 学习
一字典树 字典树,又称单词查找树,Trie树,是一种树形结构,哈希表的一个变种 二.性质 根节点不包含字符,除根节点以外的每一个节点都只包含一个字符: 从根节点到某一节点,路径上经过的字符串连接起 ...
- 字典树(Trie)详解
详解字典树(Trie) 本篇随笔简单讲解一下信息学奥林匹克竞赛中的较为常用的数据结构--字典树.字典树也叫Trie树.前缀树.顾名思义,它是一种针对字符串进行维护的数据结构.并且,它的用途超级广泛.建 ...
随机推荐
- Flutter Widgets 之 BottomNavigationBar 和 BottomNavigationBarItem
注意:无特殊说明,Flutter版本及Dart版本如下: Flutter版本: 1.12.13+hotfix.5 Dart版本: 2.7.0 BottomNavigationBar 和 BottomN ...
- SGD与Adam识别MNIST数据集
几种常见的优化函数比较:https://blog.csdn.net/w113691/article/details/82631097 ''' 基于Adam识别MNIST数据集 ''' import t ...
- OpenCV3入门(十一)图像直方图
1.直方图的概念 灰度直方图是灰度级的函数,描述的是图像中具有该灰度级的像元的个数.确定图像像素的灰度值范围,以适当的灰度间隔为单位将其划分为若干等级,以横轴表示灰度级,以纵轴表示每一灰度级具有的像素 ...
- 先导篇:SpringCloud介绍篇
1.什么是SpringCloud Spring Cloud是一系列框架的有序集合.它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册.配置中心.消息总线.负载 ...
- js获取当前日期是一年中的第几天
js获取当前日期为一年中的第几天 const currentYear = new Date().getFullYear().toString(); // 今天减今年的第一天(xxxx年01月01日) ...
- java并发编程基础概念
本次内容主要讲进程和线程.CPU核心数和线程数.CPU时间片轮转机制.上下文切换,并行和并发的基本概念以及并发编程的好处和注意事项,为java并发编程打下扎实基础. 1.什么是进程和线程 1.1 进程 ...
- 无刷新上传图片,ajax 和 iframe
iframe 上传 upload.html 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 ...
- racket学习-call/cc (let/cc)
Drracket continuation 文中使用let/cc代替call/cc Racket文档中,let/cc说明为: (let/cc k body ...+) Equivalent to (c ...
- VScode 格式化代码保存时使用ESlint修复代码
前言 eslint vs code 新买的电脑啊啊西 装VScode 配置格式化代码保存时使用ESlint修复代码头快炸了,不建议初学者用,太费时间了: 终于搞定---再也不要担心缩进,函数(名)和 ...
- vue基础----组件通信($parent,$children)
1.按照dom的父子级关系,在子组件中可以通过$parent 直接调用父组件的方法,也可得到父组件的属性. 2.在父组件中通过$childrens可以得到一个子组件数组,能够在父组件中调用子组件的方法 ...