Trie树做题记录
Trie树
字典树
- 本质上就是树上路径字符串版本
- 特定的路径表示完整的字符串,同层的相同字母合并为一个一样的字母。
B. 数字串前缀匹配 || 【一本通提高篇Trie字典树】Phone List
这题看似简单,但是调了好久。
我们正常建树,如果在遍历到某一个结点的过程中检测到当前作为一个字符串的末尾 \((cnt[p] ≠ 0)\) 。我们就认定该字符串有前缀在给出数据中。
要注意的细节:
- 多测清空。建议手动清空,\(memset\) 出题人卡常专用
- 数组大小谨慎开,动不动就MLE。
- 记得判断:两个串相同也要输出
NO
!
#include <bits/stdc++.h>
using namespace std;
int n, a[101010][70], cnt[101010], idx;
bool f = false;
char s[101010];
void insert() {
int p = 0, x;
int old = idx;
for (int i = 0; s[i]; i++) {
x = s[i] - '0';
if (a[p][x] == 0) a[p][x] = ++idx;
if (cnt[p] != 0) {
f = true;
return ;
}
p = a[p][x];
}
if(old == idx){
f = true;
return ;//没有新建任何结点
}
cnt[p]++;
}
int main() {
int t;
cin >> t;
while (t--) {
f = 0;
memset(a,0,sizeof a);
memset(cnt,0,sizeof cnt);
idx = 0;
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> s;
insert();
}
if (!f) puts("YES");
else puts("NO");
}
}
P8306 【模板】字典树
- 板子。我们在插入字符串的时候每添加(遍历)到一个字符,就将它对应的节点编号++,这样我们就能在一个位置得到有多少个单词到现在为止的前缀与它到现在为止的前缀相同。当前单词结尾时就能得到他相同前缀单词的数量。
#include <bits/stdc++.h>
using namespace std;
char s[3000010];
int a[3000010][90];
int idx;//节点编号
int cnt[3000010];
void insert(char s[]) {
int p = 0, c;
for (int i = 0; s[i]; i++) {
c = s[i] - '0';
if (a[p][c] == 0) a[p][c] = ++idx;
p = a[p][c];
cnt[p]++;
}
}
int query(char s[]) {
int d = 0, c;
for (int i = 0; s[i]; i++) {
c = s[i] - '0';//恶心题,字符串包含数字
if (a[d][c] == 0) return 0;
else d = a[d][c];
}
return cnt[d];
}
int main() {
int t;
cin >> t;
while (t--) {
for (int i = 0; i <= idx; i++) {
for (int j = 0; j < 90; j++) {
a[i][j] = 0;
}
}
for (int i = 0; i <= idx; i++) {
cnt[i] = 0;
}
idx = 0;
int n;
cin >> n;
int m;
cin >> m;
for (int i = 1; i <= n; i++) {
cin >> s;
insert(s);
}
for (int i = 1; i <= m; i++) {
cin >> s;
cout << query(s) << "\n";
}
}
}
A. 三年二班的投票
板子。
#include <bits/stdc++.h>
using namespace std;
int n, ch[1000010][30], cnt[1000010];
char s[1000010];
int idx;
void insert() {
int p = 0;
for (int i = 0; s[i]; i++) {
int x = s[i] - 'a';
if (ch[p][x] == 0) ch[p][x] = ++idx;
p = ch[p][x];//下移到当前节点(下一次起点)
}
cnt[p]++;//节点编号++
}
int query() {
int x, p = 0;
for (int i = 0; s[i]; i++) {
x = s[i] - 'a';
if (ch[p][x] == 0) return 0;
p = ch[p][x];
}
return cnt[p];
}
int main() {
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
scanf("%s", s);
insert();
}
cin >> n;
for (int i = 1; i <= n; i++) {
scanf("%s", s);
printf("%d\n", query());
}
return 0;
}
F. 字典树I
纯唐板子。
#include <bits/stdc++.h>
using namespace std;
int n,a[1010010][30],cnt[1010101],op;
char s[1001010];
int idx;//节点编号
void insert(char s[]){
int x,p = 0;
for(int i= 0;s[i];i++){
x = s[i]-'a';
if(a[p][x] == 0) a[p][x] = ++idx;
p = a[p][x];
}
cnt[p]++;
}
int query(char s[]){
int x,p = 0;
for(int i = 0;s[i];i++){
x = s[i]-'a';
if(a[p][x] == 0) return 0;
p = a[p][x];
}
return cnt[p];
}
int main(){
cin>>n;
for(int i = 1;i <= n;i++){
cin>>op>>s;
if(op == 1){
insert(s);
}else cout<<(query(s) ? "Yes" : "No")<<"\n";
}
}
G. 字典树II
弱化版本P8306 【模板】字典树,对数组大小和 \(memset\) 常数没有特殊卡常。
#include <bits/stdc++.h>
using namespace std;
int n,a[101010][30],cnt[1010101],op;
char s[101010];
int idx;//节点编号
void insert(char s[]){
int x,p = 0;
for(int i= 0;s[i];i++){
x = s[i]-'a';
if(a[p][x] == 0) a[p][x] = ++idx;
p = a[p][x];
cnt[p]++;
}
}
int query(char s[]){
int x,p = 0;
for(int i = 0;s[i];i++){
x = s[i]-'a';
if(a[p][x] == 0) return 0;
p = a[p][x];
}
return cnt[p];
}
int main(){
cin>>n;
for(int i = 1;i <= n;i++){
cin>>op>>s;
if(op == 1){
insert(s);
}else cout<<query(s)<<"\n";
}
}
Trie树做题记录的更多相关文章
- Sam做题记录
Sam做题记录 Hihocoder 后缀自动机二·重复旋律5 求一个串中本质不同的子串数 显然,答案是 \(\sum len[i]-len[fa[i]]\) Hihocoder 后缀自动机三·重复旋律 ...
- 退役IV次后做题记录
退役IV次后做题记录 我啥都不会了.... AGC023 D 如果所有的楼房都在\(S\)同一边可以直接得出答案. 否则考虑最左最右两边的票数,如果左边>=右边,那么最右边会投给左边,因为就算车 ...
- 退役III次后做题记录(扯淡)
退役III次后做题记录(扯淡) CF607E Cross Sum 计算几何屎题 直接二分一下,算出每条线的位置然后算 注意相对位置这个不能先搞出坐标,直接算角度就行了,不然会卡精度/px flag:计 ...
- 退役II次后做题记录
退役II次后做题记录 感觉没啥好更的,咕. atcoder1219 历史研究 回滚莫队. [六省联考2017]组合数问题 我是傻逼 按照组合意义等价于\(nk\)个物品,选的物品\(\mod k\) ...
- BJOI做题记录
BJOI做题记录 终于想起还要做一下历年省选题了2333 然而咕了的还是比做了的多2333 LOJ #2178. 「BJOI2017」机动训练 咕了. LOJ #2179. 「BJOI2017」树的难 ...
- FJOI2017前做题记录
FJOI2017前做题记录 2017-04-15 [ZJOI2017] 树状数组 问题转化后,变成区间随机将一个数异或一,询问两个位置的值相等的概率.(注意特判询问有一个区间的左端点为1的情况,因为题 ...
- HDU 1251 统计难题 (Trie树模板题)
题目链接:点击打开链接 Problem Description Ignatius最近遇到一个难题,老师交给他很多单词(只有小写字母组成,不会有重复的单词出现),现在老师要他统计出以某个字符串为前缀的单 ...
- 基于trie树做一个ac自动机
基于trie树做一个ac自动机 #!/usr/bin/python # -*- coding: utf-8 -*- class Node: def __init__(self): self.value ...
- UOJ 做题记录
UOJ 做题记录 其实我这么弱> >根本不会做题呢> > #21. [UR #1]缩进优化 其实想想还是一道非常丝播的题目呢> > 直接对于每个缩进长度统计一遍就好 ...
- HDU 1251 Trie树模板题
1.HDU 1251 统计难题 Trie树模板题,或者map 2.总结:用C++过了,G++就爆内存.. 题意:查找给定前缀的单词数量. #include<iostream> #incl ...
随机推荐
- tomcat 自启动脚本(普通模式)
tomcat daemon模式启停脚本 https://www.cnblogs.com/wxp100/p/14846331.html tomcat 普通模式启停脚本 vi tomcatServer.s ...
- 同步工具-Oceanus打通mysql到Iceberg
一.服务配置 已配置好gt_oneline_2,其它集群还需按照下面方式特殊配置 1.需要腾讯Oceanus同学在后端修改高途flink集群配置core-site.xml文件,增加如下配置.只能绑定一 ...
- 6.App.vue配置
1.修改<div id="app">指定动态路由,可以设置导航栏 <div id="app"> <!-- 导航栏 --> & ...
- Windows上安装MySQL详细教程
1.MySQL简介 MySQL是最流行的关系型数据库管理系统,在WEB应用方面MySQL是最好的RDBMS(Relational Database Management System:关系数据库管理系 ...
- 【论文随笔】多行为序列Transformer推荐(Multi-Behavior Sequential Transformer Recommender)
前言 今天读的论文为一篇于2022年7月发表在第45届国际计算机学会信息检索会议(SIGIR '22)的论文,文章主要为推荐系统领域提供了一个新的视角,特别是在处理用户多行为序列数据方面,提出了一种有 ...
- 【ABAQUS&Composite】composite layerup Manager从txt导入铺层信息
ABAQUS 在复合材料建模方面自由度是比较高的.官方提供了两个工具: ABAQUS/CAE中的Composite Layup Manager ABAQUS/CAE的plugin:Composites ...
- Laravel11 从0开发 Swoole-Reverb 扩展包(二) - Pusher 协议介绍
Pusher 协议概述 Pusher 协议 是一种用于实时 Web 通信的协议,它基于 WebSocket 技术,并提供了一套 发布-订阅(Pub/Sub)模式,用于让客户端(如浏览器.移动端.后端服 ...
- .NET周刊【3月第1期 2025-03-02】
国内文章 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章 https://www.cnblogs.com/shanyou/p/18737657 2025年2月25日,.NET ...
- python web服务器--WSGI/ASGI协议--web框架,三者之间的关系
在 Python Web 开发中,Web 服务器.WSGI/ASGI 协议 和 Web 框架 是三个核心组成部分,它们共同协作以实现完整的 Web 应用程序.以下是三者之间的关系和作用的详细讲解: 1 ...
- [SDR] GNU Radio 系列教程 —— GNU Radio RX PDU (接收据包操作)的基础知识(超全)
目录 1 接收概述 2 相关块介绍 2.1 相关性估计器(Correlation Estimator) 2.2 多相时钟同步(Polyphase Clock Sync) 2.3 线性均衡器(Linea ...