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树做题记录的更多相关文章

  1. Sam做题记录

    Sam做题记录 Hihocoder 后缀自动机二·重复旋律5 求一个串中本质不同的子串数 显然,答案是 \(\sum len[i]-len[fa[i]]\) Hihocoder 后缀自动机三·重复旋律 ...

  2. 退役IV次后做题记录

    退役IV次后做题记录 我啥都不会了.... AGC023 D 如果所有的楼房都在\(S\)同一边可以直接得出答案. 否则考虑最左最右两边的票数,如果左边>=右边,那么最右边会投给左边,因为就算车 ...

  3. 退役III次后做题记录(扯淡)

    退役III次后做题记录(扯淡) CF607E Cross Sum 计算几何屎题 直接二分一下,算出每条线的位置然后算 注意相对位置这个不能先搞出坐标,直接算角度就行了,不然会卡精度/px flag:计 ...

  4. 退役II次后做题记录

    退役II次后做题记录 感觉没啥好更的,咕. atcoder1219 历史研究 回滚莫队. [六省联考2017]组合数问题 我是傻逼 按照组合意义等价于\(nk\)个物品,选的物品\(\mod k\) ...

  5. BJOI做题记录

    BJOI做题记录 终于想起还要做一下历年省选题了2333 然而咕了的还是比做了的多2333 LOJ #2178. 「BJOI2017」机动训练 咕了. LOJ #2179. 「BJOI2017」树的难 ...

  6. FJOI2017前做题记录

    FJOI2017前做题记录 2017-04-15 [ZJOI2017] 树状数组 问题转化后,变成区间随机将一个数异或一,询问两个位置的值相等的概率.(注意特判询问有一个区间的左端点为1的情况,因为题 ...

  7. HDU 1251 统计难题 (Trie树模板题)

    题目链接:点击打开链接 Problem Description Ignatius最近遇到一个难题,老师交给他很多单词(只有小写字母组成,不会有重复的单词出现),现在老师要他统计出以某个字符串为前缀的单 ...

  8. 基于trie树做一个ac自动机

    基于trie树做一个ac自动机 #!/usr/bin/python # -*- coding: utf-8 -*- class Node: def __init__(self): self.value ...

  9. UOJ 做题记录

    UOJ 做题记录 其实我这么弱> >根本不会做题呢> > #21. [UR #1]缩进优化 其实想想还是一道非常丝播的题目呢> > 直接对于每个缩进长度统计一遍就好 ...

  10. HDU 1251 Trie树模板题

    1.HDU 1251 统计难题  Trie树模板题,或者map 2.总结:用C++过了,G++就爆内存.. 题意:查找给定前缀的单词数量. #include<iostream> #incl ...

随机推荐

  1. react事件 报错Cannot read property 'setState' of undefined

    import React, { Component } from "react"; export class TestHanderClick extends Component { ...

  2. 从挑战到突破:HBlock定义智算存储新范式!

    近日,由DOIT传媒主办,中国计算机学会信息存储专委会.武汉光电国家研究中心.百易存储研究院支持的2024中国数据与存储峰会在北京召开.此次峰会以"智数据 AI未来"为主题,天翼云 ...

  3. 蝉联第一,天翼云电脑持续领跑中国DaaS市场!

    近日,IDC发布的<中国虚拟桌面软件及云服务市场半年跟踪报告>数据显示,中国电信天翼云在2023年上半年中国桌面即服务(Desktop as a Service,以下简称"Daa ...

  4. DataV过滤器

    人才库: return data.filter(function (item) { return item.职级 === ''; }) 区县分析:   //一级指标 const t = Object. ...

  5. FLink17--聚合函数-AggWindowApp

    一.依赖 二.代码 package net.xdclass.class11; import org.apache.flink.api.common.RuntimeExecutionMode; impo ...

  6. HT-018 Div3 构造 题解 [ 黄 ] [ 数学 ] [ 结论 ]

    构造:结论题,gcy数竞大佬tql%%%orz. 结论 先放结论:如果 \(x \bmod 4=2\) ,那么 \(x\) 无法被表示为 \(a^2-b^2\) 的形式:除此之外的其他数都可以. 证明 ...

  7. 如何配置 maven 编译插件的 JDK 版本

    普通maven项目配置编译器版本 参考maven官方文档 Setting the -source and -target of the Java Compiler maven有2种方法设置编译JDK版 ...

  8. 动手学深度学习-python基础知识介绍part1

    基础详解-part1 import torch x=torch.arange(12) x x.shape x.numel() #数组中元素的总数 # 修改形状 x.reshape(3,4) torch ...

  9. 解锁DeepSeek深度应用,天翼云GPU云主机强势破局!

    在人工智能重塑世界的当下,一场影响深远的科技变革正在悄然上演,DeepSeek系列模型在诸多领域掀起热潮.企业级AI模型的训练与部署,不仅是技术的角力场,更是决定企业兴衰的生死线.每一次算法的迭代革新 ...

  10. MarkDown学习使用图片

    学习MarkDown使用